+++ /dev/null
-Certain files in this directory are licensed by the GNU
-General Public License version 2 (GPLv2). By default these
-files are not built and linked into MiniOs. Enabling them
-will cause the whole work to become covered by the GPLv2.
-
-The current set of GPLv2 features are:
-CONFIG_TPMFRONT
-CONFIG_TPMBACK
-CONFIG_TPM_TIS
-
-Do not use these if you do not want your MiniOS build to become
-GPL licensed!
-
-Copyright (c) 2009 Citrix Systems, Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
+++ /dev/null
-#
-# Compare $(1) and $(2) and replace $(2) with $(1) if they differ
-#
-# Typically $(1) is a newly generated file and $(2) is the target file
-# being regenerated. This prevents changing the timestamp of $(2) only
-# due to being auto regenereated with the same contents.
-define move-if-changed
- if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
-endef
-
-# cc-option: Check if compiler supports first option, else fall back to second.
-#
-# This is complicated by the fact that unrecognised -Wno-* options:
-# (a) are ignored unless the compilation emits a warning; and
-# (b) even then produce a warning rather than an error
-# To handle this we do a test compile, passing the option-under-test, on a code
-# fragment that will always produce a warning (integer assigned to pointer).
-# We then grep for the option-under-test in the compiler's output, the presence
-# of which would indicate an "unrecognized command-line option" warning/error.
-#
-# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
-cc-option = $(shell if test -z "`echo 'void*p=1;' | \
- $(1) $(2) -S -o /dev/null -x c - 2>&1 | grep -- $(2) -`"; \
- then echo "$(2)"; else echo "$(3)"; fi ;)
-
-# Compatibility with Xen's stubdom build environment. If we are building
-# stubdom, some XEN_ variables are set, set MINIOS_ variables accordingly.
-#
-ifneq ($(XEN_ROOT),)
-MINI-OS_ROOT=$(XEN_ROOT)/extras/mini-os
-else
-MINI-OS_ROOT=$(TOPLEVEL_DIR)
-endif
-export MINI-OS_ROOT
-
-ifneq ($(XEN_TARGET_ARCH),)
-MINIOS_TARGET_ARCH = $(XEN_TARGET_ARCH)
-else
-MINIOS_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/ \
- -e s/i86pc/x86_32/ -e s/amd64/x86_64/ \
- -e s/armv7.*/arm32/ -e s/armv8.*/arm64/ \
- -e s/aarch64/arm64/)
-
-MINIOS_TARGET_ARCH ?= $(MINIOS_COMPILE_ARCH)
-endif
-
-libc = $(stubdom)
-
-XEN_INTERFACE_VERSION := 0x00030205
-export XEN_INTERFACE_VERSION
-
-# Try to find out the architecture family TARGET_ARCH_FAM.
-# First check whether x86_... is contained (for x86_32, x86_32y, x86_64).
-# If not x86 then use $(MINIOS_TARGET_ARCH)
-ifeq ($(findstring x86_,$(MINIOS_TARGET_ARCH)),x86_)
-TARGET_ARCH_FAM = x86
-else
-TARGET_ARCH_FAM = $(MINIOS_TARGET_ARCH)
-endif
-
-# The architecture family directory below mini-os.
-TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM)
-
-# Export these variables for possible use in architecture dependent makefiles.
-export TARGET_ARCH_DIR
-export TARGET_ARCH_FAM
-
-# This is used for architecture specific links.
-# This can be overwritten from arch specific rules.
-ARCH_LINKS =
-
-# The path pointing to the architecture specific header files.
-ARCH_INC := $(TARGET_ARCH_FAM)
-
-# For possible special header directories.
-# This can be overwritten from arch specific rules.
-EXTRA_INC = $(ARCH_INC)
-
-# Include the architecture family's special makerules.
-# This must be before include minios.mk!
-include $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
-
-extra_incl := $(foreach dir,$(EXTRA_INC),-isystem $(MINI-OS_ROOT)/include/$(dir))
-
-DEF_CPPFLAGS += -isystem $(MINI-OS_ROOT)/include
-DEF_CPPFLAGS += -D__MINIOS__
-
-ifeq ($(libc),y)
-DEF_CPPFLAGS += -DHAVE_LIBC
-DEF_CPPFLAGS += -isystem $(MINI-OS_ROOT)/include/posix
-DEF_CPPFLAGS += -isystem $(XEN_ROOT)/tools/xenstore/include
-endif
-
-ifneq ($(LWIPDIR),)
-lwip=y
-DEF_CPPFLAGS += -DHAVE_LWIP
-DEF_CPPFLAGS += -isystem $(LWIPDIR)/src/include
-DEF_CPPFLAGS += -isystem $(LWIPDIR)/src/include/ipv4
-endif
+++ /dev/null
-# Common Makefile for mini-os.
-#
-# Every architecture directory below mini-os/arch has to have a
-# Makefile and a arch.mk.
-#
-
-OBJ_DIR=$(CURDIR)
-TOPLEVEL_DIR=$(CURDIR)
-
-ifeq ($(MINIOS_CONFIG),)
-include Config.mk
-else
-EXTRA_DEPS += $(MINIOS_CONFIG)
-include $(MINIOS_CONFIG)
-endif
-
-include $(MINI-OS_ROOT)/config/MiniOS.mk
-
-# Configuration defaults
-CONFIG_START_NETWORK ?= y
-CONFIG_SPARSE_BSS ?= y
-CONFIG_QEMU_XS_ARGS ?= n
-CONFIG_TEST ?= n
-CONFIG_PCIFRONT ?= n
-CONFIG_BLKFRONT ?= y
-CONFIG_TPMFRONT ?= n
-CONFIG_TPM_TIS ?= n
-CONFIG_TPMBACK ?= n
-CONFIG_NETFRONT ?= y
-CONFIG_FBFRONT ?= y
-CONFIG_KBDFRONT ?= y
-CONFIG_CONSFRONT ?= y
-CONFIG_XENBUS ?= y
-CONFIG_XC ?=y
-CONFIG_LWIP ?= $(lwip)
-
-# Export config items as compiler directives
-flags-$(CONFIG_START_NETWORK) += -DCONFIG_START_NETWORK
-flags-$(CONFIG_SPARSE_BSS) += -DCONFIG_SPARSE_BSS
-flags-$(CONFIG_QEMU_XS_ARGS) += -DCONFIG_QEMU_XS_ARGS
-flags-$(CONFIG_PCIFRONT) += -DCONFIG_PCIFRONT
-flags-$(CONFIG_BLKFRONT) += -DCONFIG_BLKFRONT
-flags-$(CONFIG_TPMFRONT) += -DCONFIG_TPMFRONT
-flags-$(CONFIG_TPM_TIS) += -DCONFIG_TPM_TIS
-flags-$(CONFIG_TPMBACK) += -DCONFIG_TPMBACK
-flags-$(CONFIG_NETFRONT) += -DCONFIG_NETFRONT
-flags-$(CONFIG_KBDFRONT) += -DCONFIG_KBDFRONT
-flags-$(CONFIG_FBFRONT) += -DCONFIG_FBFRONT
-flags-$(CONFIG_CONSFRONT) += -DCONFIG_CONSFRONT
-flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS
-
-DEF_CFLAGS += $(flags-y)
-
-# Symlinks and headers that must be created before building the C files
-GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/$(TARGET_ARCH_FAM)/mini-os
-
-EXTRA_DEPS += $(GENERATED_HEADERS)
-
-# Include common mini-os makerules.
-include minios.mk
-
-# Set tester flags
-# CFLAGS += -DBLKTEST_WRITE
-
-# Define some default flags for linking.
-LDLIBS :=
-APP_LDLIBS :=
-LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
-LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(MINIOS_TARGET_ARCH).lds
-
-# Prefix for global API names. All other symbols are localised before
-# linking with EXTRA_OBJS.
-GLOBAL_PREFIX := xenos_
-EXTRA_OBJS =
-
-TARGET := mini-os
-
-# Subdirectories common to mini-os
-SUBDIRS := lib xenbus console
-
-src-$(CONFIG_BLKFRONT) += blkfront.c
-src-$(CONFIG_TPMFRONT) += tpmfront.c
-src-$(CONFIG_TPM_TIS) += tpm_tis.c
-src-$(CONFIG_TPMBACK) += tpmback.c
-src-y += daytime.c
-src-y += events.c
-src-$(CONFIG_FBFRONT) += fbfront.c
-src-y += gntmap.c
-src-y += gnttab.c
-src-y += hypervisor.c
-src-y += kernel.c
-src-y += lock.c
-src-y += main.c
-src-y += mm.c
-src-$(CONFIG_NETFRONT) += netfront.c
-src-$(CONFIG_PCIFRONT) += pcifront.c
-src-y += sched.c
-src-$(CONFIG_TEST) += test.c
-
-src-y += lib/ctype.c
-src-y += lib/math.c
-src-y += lib/printf.c
-src-y += lib/stack_chk_fail.c
-src-y += lib/string.c
-src-y += lib/sys.c
-src-y += lib/xmalloc.c
-src-$(CONFIG_XENBUS) += lib/xs.c
-
-src-$(CONFIG_XENBUS) += xenbus/xenbus.c
-
-src-y += console/console.c
-src-y += console/xencons_ring.c
-src-$(CONFIG_CONSFRONT) += console/xenbus.c
-
-# The common mini-os objects to build.
-APP_OBJS :=
-OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(src-y))
-
-.PHONY: default
-default: $(OBJ_DIR)/$(TARGET)
-
-# Create special architecture specific links. The function arch_links
-# has to be defined in arch.mk (see include above).
-ifneq ($(ARCH_LINKS),)
-$(ARCH_LINKS):
- $(arch_links)
-endif
-
-include/list.h: include/minios-external/bsd-sys-queue-h-seddery include/minios-external/bsd-sys-queue.h
- perl $^ --prefix=minios >$@.new
- $(call move-if-changed,$@.new,$@)
-
-# Used by stubdom's Makefile
-.PHONY: links
-links: $(GENERATED_HEADERS)
-
-include/mini-os:
- ln -sf . $@
-
-include/$(TARGET_ARCH_FAM)/mini-os:
- ln -sf . $@
-
-.PHONY: arch_lib
-arch_lib:
- $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) || exit 1;
-
-ifeq ($(CONFIG_LWIP),y)
-# lwIP library
-LWC := $(shell find $(LWIPDIR)/src -type f -name '*.c')
-LWC := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC))
-LWO := $(patsubst %.c,%.o,$(LWC))
-LWO += $(OBJ_DIR)/lwip-arch.o
-ifeq ($(CONFIG_NETFRONT),y)
-LWO += $(OBJ_DIR)/lwip-net.o
-endif
-
-$(OBJ_DIR)/lwip.a: $(LWO)
- $(RM) $@
- $(AR) cqs $@ $^
-
-OBJS += $(OBJ_DIR)/lwip.a
-endif
-
-OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
-
-ifeq ($(libc),y)
-ifeq ($(CONFIG_XC),y)
-APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc-$(XEN_TARGET_ARCH) -whole-archive -lxenguest -lxenctrl -no-whole-archive
-endif
-APP_LDLIBS += -lpci
-APP_LDLIBS += -lz
-APP_LDLIBS += -lm
-LDLIBS += -lc
-endif
-
-ifneq ($(APP_OBJS)-$(lwip),-y)
-OBJS := $(filter-out $(OBJ_DIR)/daytime.o, $(OBJS))
-endif
-
-$(OBJ_DIR)/$(TARGET)_app.o: $(APP_OBJS) app.lds
- $(LD) -r -d $(LDFLAGS) -\( $^ -\) $(APP_LDLIBS) --undefined main -o $@
-
-ifneq ($(APP_OBJS),)
-APP_O=$(OBJ_DIR)/$(TARGET)_app.o
-endif
-
-$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
- $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
- $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
- $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
- gzip -f -9 -c $@ >$@.gz
-
-.PHONY: clean arch_clean
-
-arch_clean:
- $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) clean || exit 1;
-
-clean: arch_clean
- for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \
- rm -f $$dir/*.o; \
- done
- rm -f include/list.h
- rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz
- find . $(OBJ_DIR) -type l | xargs rm -f
- $(RM) $(OBJ_DIR)/lwip.a $(LWO)
- rm -f tags TAGS
-
-
-define all_sources
- ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
-endef
-
-.PHONY: cscope
-cscope:
- $(all_sources) > cscope.files
- cscope -k -b -q
-
-.PHONY: tags
-tags:
- $(all_sources) | xargs ctags
-
-.PHONY: TAGS
-TAGS:
- $(all_sources) | xargs etags
+++ /dev/null
- Minimal OS
- ----------
-
-This shows some of the stuff that any guest OS will have to set up.
-
-This includes:
-
- * installing a virtual exception table
- * handling virtual exceptions
- * handling asynchronous events
- * enabling/disabling async events
- * parsing start_info struct at start-of-day
- * registering virtual interrupt handlers (for timer interrupts)
- * a simple page and memory allocator
- * minimal libc support
- * minimal Copy-on-Write support
- * network, block, framebuffer support
- * transparent access to FileSystem exports (see tools/fs-back)
-
-- to build it just type make.
-
-- to build it with TCP/IP support, download LWIP 1.3.2 source code and type
-
- make LWIPDIR=/path/to/lwip/source
-
-- to build it with much better libc support, see the stubdom/ directory
-
-- to start it do the following in domain0
- # xl create -c domain_config
-
-This starts the kernel and prints out a bunch of stuff and then once every
-second the system time.
-
-If you have setup a disk in the config file (e.g.
-disk = [ 'file:/tmp/foo,hda,r' ] ), it will loop reading it. If that disk is
-writable (e.g. disk = [ 'file:/tmp/foo,hda,w' ] ), it will write data patterns
-and re-read them.
-
-If you have setup a network in the config file (e.g. vif = [''] ), it will
-print incoming packets.
-
-If you have setup a VFB in the config file (e.g. vfb = ['type=sdl'] ), it will
-show a mouse with which you can draw color squares.
-
-If you have compiled it with TCP/IP support, it will run a daytime server on
-TCP port 13.
+++ /dev/null
-SECTIONS
-{
- .app.bss : {
- __app_bss_start = . ;
- *(.bss .bss.*)
- *(COMMON)
- *(.lbss .lbss.*)
- *(LARGE_COMMON)
- __app_bss_end = . ;
- }
-}
+++ /dev/null
-@ Offset of the kernel within the RAM. This is a Linux/zImage convention which we
-@ rely on for now.
-#define ZIMAGE_KERNEL_OFFSET 0x8000
-
-.section .text
-
-.globl _start
-_start:
- @ zImage header
-.rept 8
- mov r0, r0
-.endr
- b reset
- .word 0x016f2818 @ Magic numbers to help the loader
- .word 0 @ zImage start address (0 = relocatable)
- .word _edata - _start @ zImage end address (excludes bss section)
- @ end of zImage header
-
-@ Called at boot time. Sets up MMU, exception vectors and stack, and then calls C arch_init() function.
-@ => r2 -> DTB
-@ <= never returns
-@ Note: this boot code needs to be within the first (1MB - ZIMAGE_KERNEL_OFFSET) of _start.
-reset:
- @ Problem: the C code wants to be at a known address (_start), but Xen might
- @ load us anywhere. We initialise the MMU (mapping virtual to physical @ addresses)
- @ so everything ends up where the code expects it to be.
- @
- @ We calculate the offet between where the linker thought _start would be and where
- @ it actually is and initialise the page tables to have that offset for every page.
- @
- @ When we turn on the MMU, we're still executing at the old address. We don't want
- @ the code to disappear from under us. So we have to do the mapping in stages:
- @
- @ 1. set up a mapping to our current page from both its current and desired addresses
- @ 2. enable the MMU
- @ 3. jump to the new address
- @ 4. remap all the other pages with the calculated offset
-
- adr r1, _start @ r1 = physical address of _start
- ldr r3, =_start @ r3 = (desired) virtual address of _start
- sub r9, r1, r3 @ r9 = (physical - virtual) offset
-
- ldr r7, =_page_dir @ r7 = (desired) virtual addr of translation table
- add r1, r7, r9 @ r1 = physical addr of translation table
-
- @ Tell the system where our page table is located.
- @ This is the 16 KB top-level translation table, in which
- @ each word maps one 1MB virtual section to a physical section.
- @ Note: We leave TTBCR as 0, meaning that only TTBR0 is used and
- @ we use the short-descriptor format (32-bit physical addresses).
- orr r0, r1, #0b0001011 @ Sharable, Inner/Outer Write-Back Write-Allocate Cacheable
- mcr p15, 0, r0, c2, c0, 0 @ set TTBR0
-
- @ Set access permission for domains.
- @ Domains are deprecated, but we have to configure them anyway.
- @ We mark every page as being domain 0 and set domain 0 to "client mode"
- @ (client mode = use access flags in page table).
- mov r0, #1 @ 1 = client
- mcr p15, 0, r0, c3, c0, 0 @ DACR
-
- @ Template (flags) for a 1 MB page-table entry.
- @ TEX[2:0] C B = 001 1 1 (outer and inner write-back, write-allocate)
- ldr r8, =(0x2 + /* Section entry */ \
- 0xc + /* C B */ \
- (3 << 10) + /* Read/write */ \
- (1 << 12) + /* TEX */ \
- (1 << 16) + /* Sharable */ \
- (1<<19)) /* Non-secure */
- @ r8 = template page table entry
-
- @ Add an entry for the current physical section, at the old and new
- @ addresses. It's OK if they're the same.
- mov r0, pc, lsr#20
- mov r0, r0, lsl#20 @ r0 = physical address of this code's section start
- orr r3, r0, r8 @ r3 = table entry for this section
- ldr r4, =_start @ r4 = desired virtual address of this section
- str r3, [r1, r4, lsr#18] @ map desired virtual section to this code
- str r3, [r1, r0, lsr#18] @ map current section to this code too
-
- @ Invalidate TLB
- dsb @ Caching is off, but must still prevent reordering
- mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
-
- @ Enable MMU / SCTLR
- mrc p15, 0, r1, c1, c0, 0 @ SCTLR
- orr r1, r1, #3 << 11 @ enable icache, branch prediction
- orr r1, r1, #4 + 1 @ enable dcache, MMU
- mcr p15, 0, r1, c1, c0, 0 @ SCTLR
- isb
-
- ldr r1, =stage2 @ Virtual address of stage2
- bx r1
-
-@ Called once the MMU is enabled. The boot code and the page table are mapped,
-@ but nothing else is yet.
-@
-@ => r2 -> dtb (physical)
-@ r7 = virtual address of page table
-@ r8 = section entry template (flags)
-@ r9 = desired physical - virtual offset
-@ pc -> somewhere in newly-mapped virtual code section
-stage2:
- @ Invalidate TLB
- mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
- isb
-
- @ The new mapping has now taken effect:
- @ r7 -> page_dir
-
- @ Fill in the whole top-level translation table (at page_dir).
- @ Populate the whole pagedir with 1MB section descriptors.
-
- mov r1, r7 @ r1 -> first section entry
- add r3, r1, #4*4*1024 @ limit (4 GB address space, 4 byte entries)
- orr r0, r8, r9 @ r0 = entry mapping section zero to start of physical RAM
-1:
- str r0, [r1],#4 @ write the section entry
- add r0, r0, #1 << 20 @ next physical page (wraps)
- cmp r1, r3
- bne 1b
-
- @ Invalidate TLB
- dsb
- mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
- isb
-
- @ Set VBAR -> exception_vector_table
- @ SCTLR.V = 0
- adr r0, exception_vector_table
- mcr p15, 0, r0, c12, c0, 0
-
- @ Enable hardware floating point:
- @ 1. Access to CP10 and CP11 must be enabled in the Coprocessor Access
- @ Control Register (CP15.CACR):
- mrc p15, 0, r1, c1, c0, 2 @ CACR
- orr r1, r1, #(3 << 20) + (3 << 22) @ full access for CP10 & CP11
- mcr p15, 0, r1, c1, c0, 2
- @ 2. The EN bit in the FPEXC register must be set:
- vmrs r0, FPEXC
- orr r0, r0, #1<<30 @ EN (enable)
- vmsr FPEXC, r0
-
- @ Initialise 16 KB stack
- ldr sp, =_boot_stack_end
-
- sub r0, r2, r9 @ r0 -> device tree (virtual address)
- mov r1, r9 @ r1 = physical_address_offset
-
- b arch_init
-
-.pushsection .bss
-@ Note: calling arch_init zeroes out this region.
-.align 12
-.globl shared_info_page
-shared_info_page:
- .fill (1024), 4, 0x0
-
-.align 3
-.globl irqstack
-.globl irqstack_end
-irqstack:
- .fill (1024), 4, 0x0
-irqstack_end:
-
-fault_dump:
- .fill 18, 4, 0x0 @ On fault, we save the registers + CPSR + handler address
-
-.popsection
-
-fault:
- cpsid aif @ Disable interrupts
-
- ldr r13, =fault_dump
- stmia r13, {r0-r12} @ Dump the non-banked registers directly (well, unless from FIQ mode)
- str r14, [r13, #15 << 2] @ Our r14 is the faulting r15
- mov r0, r13
-
- @ Save the caller's CPSR (our SPSR) too.
- mrs r1, SPSR
- str r1, [r13, #16 << 2]
-
- @ Switch to the mode we came from to get r13 and r14.
- @ If coming from user mode, use System mode instead so we're still
- @ privileged.
- and r1, r1, #0x1f @ r1 = SPSR mode
- cmp r1, #0x10 @ If from User mode
- moveq r1, #0x1f @ Then use System mode instead
-
- mrs r3, CPSR @ r3 = our CPSR
- bic r2, r3, #0x1f
- orr r2, r2, r1
- msr CPSR, r2 @ Change to mode r1
-
- @ Save old mode's r13, r14
- str r13, [r0, #13 << 2]
- str r14, [r0, #14 << 2]
-
- msr CPSR, r3 @ Back to fault mode
-
- ldr r1, [r0, #17 << 2]
- sub r1, r1, #12 @ Fix to point at start of handler
- str r1, [r0, #17 << 2]
-
- @ Call C code to format the register dump.
- @ Clobbers the stack, but we're not going to return anyway.
- ldr sp, =_boot_stack_end
- bl dump_registers
- b do_exit
-
-@ We want to store a unique value to identify this handler, without corrupting
-@ any of the registers. So, we store r15 (which will point just after the branch).
-@ Later, we subtract 12 so the user gets pointed at the start of the exception
-@ handler.
-#define FAULT(name) \
-.globl fault_##name; \
-fault_##name: \
- ldr r13, =fault_dump; \
- str r15, [r13, #17 << 2]; \
- b fault
-
-FAULT(reset)
-FAULT(undefined_instruction)
-FAULT(svc)
-FAULT(prefetch_call)
-FAULT(prefetch_abort)
-FAULT(data_abort)
-
-@ exception base address
-.align 5
-.globl exception_vector_table
-@ Note: remember to call CLREX if returning from an exception:
-@ "The architecture enables the local monitor to treat any exclusive store as
-@ matching a previous LDREX address. For this reason, use of the CLREX
-@ instruction to clear an existing tag is required on context switches."
-@ -- ARM Cortex-A Series Programmer’s Guide (Version: 4.0)
-exception_vector_table:
- b fault_reset
- b fault_undefined_instruction
- b fault_svc
- b fault_prefetch_call
- b fault_prefetch_abort
- b fault_data_abort
- b irq_handler @ IRQ
- .word 0xe7f000f0 @ abort on FIQ
-
-@ Call fault_undefined_instruction in "Undefined mode"
-bug:
- .word 0xe7f000f0 @ und/udf - a "Permanently Undefined" instruction
-
-irq_handler:
- ldr sp, =irqstack_end
- push {r0 - r12, r14}
-
- ldr r0, IRQ_handler
- cmp r0, #0
- beq bug
- blx r0 @ call handler
-
- @ Return from IRQ
- pop {r0 - r12, r14}
- clrex
- subs pc, lr, #4
-
-.globl IRQ_handler
-IRQ_handler:
- .long 0x0
-
-
-.globl __arch_switch_threads
-@ => r0 = &prev->sp
-@ r1 = &next->sp
-@ <= returns to next thread's saved return address
-__arch_switch_threads:
- push {r4-r11} @ Store callee-saved registers to old thread's stack
- stmia r0, {sp, lr} @ Store current sp and ip to prev's struct thread
-
- ldmia r1, {sp, lr} @ Load new sp, ip from next's struct thread
- pop {r4-r11} @ Load callee-saved registers from new thread's stack
-
- bx lr
-
-@ This is called if you try to divide by zero. For now, we make a supervisor call,
-@ which will make us halt.
-.globl raise
-raise:
- svc 0
-
-.globl arm_start_thread
-arm_start_thread:
- pop {r0, r1}
- @ r0 = user data
- @ r1 -> thread's main function
- ldr lr, =exit_thread
- bx r1
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/events.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/console.h>
-
-static void virq_debug(evtchn_port_t port, struct pt_regs *regs, void *params)
-{
- printk("Received a virq_debug event\n");
-}
-
-evtchn_port_t debug_port = -1;
-void arch_init_events(void)
-{
- debug_port = bind_virq(VIRQ_DEBUG, (evtchn_handler_t)virq_debug, 0);
- if(debug_port == -1)
- BUG();
- unmask_evtchn(debug_port);
-}
-
-void arch_unbind_ports(void)
-{
- if(debug_port != -1)
- {
- mask_evtchn(debug_port);
- unbind_evtchn(debug_port);
- }
-}
-
-void arch_fini_events(void)
-{
-}
+++ /dev/null
-/******************************************************************************
- * hypercall.S
- *
- * Xen hypercall wrappers
- *
- * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <xen/xen.h>
-
-#define __HVC(imm16) .long ((0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F)) & 0xFFFFFFFF)
-
-#define XEN_IMM 0xEA1
-
-#define HYPERCALL_SIMPLE(hypercall) \
-.globl HYPERVISOR_##hypercall; \
-.align 4,0x90; \
-HYPERVISOR_##hypercall: \
- mov r12, #__HYPERVISOR_##hypercall; \
- __HVC(XEN_IMM); \
- mov pc, lr;
-
-#define _hypercall0 HYPERCALL_SIMPLE
-#define _hypercall1 HYPERCALL_SIMPLE
-#define _hypercall2 HYPERCALL_SIMPLE
-#define _hypercall3 HYPERCALL_SIMPLE
-#define _hypercall4 HYPERCALL_SIMPLE
-
-_hypercall2(sched_op);
-_hypercall2(memory_op);
-_hypercall2(event_channel_op);
-_hypercall2(xen_version);
-_hypercall3(console_io);
-_hypercall1(physdev_op);
-_hypercall3(grant_table_op);
-_hypercall3(vcpu_op);
-_hypercall1(sysctl);
-_hypercall1(domctl);
-_hypercall2(hvm_op);
-_hypercall1(xsm_op);
+++ /dev/null
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- /* Note: we currently assume that Xen will load the kernel image
- * at start-of-RAM + 0x8000. We use this initial 32 KB for the stack
- * and translation tables.
- */
- _boot_stack = 0x400000; /* 16 KB boot stack */
- _boot_stack_end = 0x404000;
- _page_dir = 0x404000; /* 16 KB translation table */
- . = 0x408000;
- _text = .; /* Text and read-only data */
- .text : {
- *(.text)
- *(.gnu.warning)
- } = 0x9090
-
- _etext = .; /* End of text section */
-
- .rodata : { *(.rodata) *(.rodata.*) }
- . = ALIGN(4096);
- _erodata = .;
-
- /* newlib initialization functions */
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
-
- .ctors : {
- __CTOR_LIST__ = .;
- *(.ctors)
- CONSTRUCTORS
- LONG(0)
- __CTOR_END__ = .;
- }
-
- .dtors : {
- __DTOR_LIST__ = .;
- *(.dtors)
- LONG(0)
- __DTOR_END__ = .;
- }
-
- .data : { /* Data */
- *(.data)
- }
-
- /* Note: linker will insert any extra sections here, just before .bss */
-
- .bss : {
- _edata = .; /* End of data included in image */
- /* Nothing after here is included in the zImage's size */
-
- __bss_start = .;
- *(.bss)
- *(.app.bss)
- }
- _end = . ;
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.text.exit)
- *(.data.exit)
- *(.exitcall.exit)
- }
-
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
-}
+++ /dev/null
-#include <mini-os/console.h>
-#include <xen/memory.h>
-#include <arch_mm.h>
-#include <mini-os/hypervisor.h>
-#include <libfdt.h>
-#include <lib.h>
-
-uint32_t physical_address_offset;
-
-unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
-{
- // FIXME
- BUG();
-}
-
-void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p)
-{
- int memory;
- int prop_len = 0;
- const uint64_t *regs;
-
- printk(" _text: %p(VA)\n", &_text);
- printk(" _etext: %p(VA)\n", &_etext);
- printk(" _erodata: %p(VA)\n", &_erodata);
- printk(" _edata: %p(VA)\n", &_edata);
- printk(" stack start: %p(VA)\n", _boot_stack);
- printk(" _end: %p(VA)\n", &_end);
-
- if (fdt_num_mem_rsv(device_tree) != 0)
- printk("WARNING: reserved memory not supported!\n");
-
- memory = fdt_node_offset_by_prop_value(device_tree, -1, "device_type", "memory", sizeof("memory"));
- if (memory < 0) {
- printk("No memory found in FDT!\n");
- BUG();
- }
-
- /* Xen will always provide us at least one bank of memory.
- * Mini-OS will use the first bank for the time-being. */
- regs = fdt_getprop(device_tree, memory, "reg", &prop_len);
-
- /* The property must contain at least the start address
- * and size, each of which is 8-bytes. */
- if (regs == NULL || prop_len < 16) {
- printk("Bad 'reg' property: %p %d\n", regs, prop_len);
- BUG();
- }
-
- unsigned int end = (unsigned int) &_end;
- paddr_t mem_base = fdt64_to_cpu(regs[0]);
- uint64_t mem_size = fdt64_to_cpu(regs[1]);
- printk("Found memory at 0x%llx (len 0x%llx)\n",
- (unsigned long long) mem_base, (unsigned long long) mem_size);
-
- BUG_ON(to_virt(mem_base) > (void *) &_text); /* Our image isn't in our RAM! */
- *start_pfn_p = PFN_UP(to_phys(end));
- uint64_t heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);
- *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
-
- printk("Using pages %lu to %lu as free space for heap.\n", *start_pfn_p, *max_pfn_p);
-
- /* The device tree is probably in memory that we're about to hand over to the page
- * allocator, so move it to the end and reserve that space.
- */
- uint32_t fdt_size = fdt_totalsize(device_tree);
- void *new_device_tree = to_virt(((*max_pfn_p << PAGE_SHIFT) - fdt_size) & PAGE_MASK);
- if (new_device_tree != device_tree) {
- memmove(new_device_tree, device_tree, fdt_size);
- }
- device_tree = new_device_tree;
- *max_pfn_p = to_phys(new_device_tree) >> PAGE_SHIFT;
-}
-
-void arch_init_p2m(unsigned long max_pfn)
-{
-}
-
-void arch_init_demand_mapping_area(unsigned long cur_pfn)
-{
-}
-
-/* Get Xen's suggested physical page assignments for the grant table. */
-static paddr_t get_gnttab_base(void)
-{
- int hypervisor;
- int len = 0;
- const uint64_t *regs;
- paddr_t gnttab_base;
-
- hypervisor = fdt_node_offset_by_compatible(device_tree, -1, "xen,xen");
- BUG_ON(hypervisor < 0);
-
- regs = fdt_getprop(device_tree, hypervisor, "reg", &len);
- /* The property contains the address and size, 8-bytes each. */
- if (regs == NULL || len < 16) {
- printk("Bad 'reg' property: %p %d\n", regs, len);
- BUG();
- }
-
- gnttab_base = fdt64_to_cpu(regs[0]);
-
- printk("FDT suggests grant table base %llx\n", (unsigned long long) gnttab_base);
-
- return gnttab_base;
-}
-
-grant_entry_t *arch_init_gnttab(int nr_grant_frames)
-{
- struct xen_add_to_physmap xatp;
- struct gnttab_setup_table setup;
- xen_pfn_t frames[nr_grant_frames];
- paddr_t gnttab_table;
- int i, rc;
-
- gnttab_table = get_gnttab_base();
-
- for (i = 0; i < nr_grant_frames; i++)
- {
- xatp.domid = DOMID_SELF;
- xatp.size = 0; /* Seems to be unused */
- xatp.space = XENMAPSPACE_grant_table;
- xatp.idx = i;
- xatp.gpfn = (gnttab_table >> PAGE_SHIFT) + i;
- rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
- BUG_ON(rc != 0);
- }
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = nr_grant_frames;
- set_xen_guest_handle(setup.frame_list, frames);
- HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (setup.status != 0)
- {
- printk("GNTTABOP_setup_table failed; status = %d\n", setup.status);
- BUG();
- }
-
- return to_virt(gnttab_table);
-}
+++ /dev/null
-/******************************************************************************
- * panic.c
- *
- * Displays a register dump and stack trace for debugging.
- *
- * Copyright (c) 2014, Thomas Leonard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/console.h>
-#include <arch_mm.h>
-
-extern int irqstack[];
-extern int irqstack_end[];
-
-typedef void handler(void);
-
-extern handler fault_reset;
-extern handler fault_undefined_instruction;
-extern handler fault_svc;
-extern handler fault_prefetch_call;
-extern handler fault_prefetch_abort;
-extern handler fault_data_abort;
-
-void dump_registers(int *saved_registers) {
- static int in_dump = 0;
- int *sp, *stack_top, *x;
- char *fault_name;
- void *fault_handler;
- int i;
-
- if (in_dump)
- {
- printk("Crash while in dump_registers! Not generating a second report.\n");
- return;
- }
-
- in_dump = 1;
-
- fault_handler = (handler *) saved_registers[17];
- if (fault_handler == fault_reset)
- fault_name = "reset";
- else if (fault_handler == fault_undefined_instruction)
- fault_name = "undefined_instruction";
- else if (fault_handler == fault_svc)
- fault_name = "svc";
- else if (fault_handler == fault_prefetch_call)
- fault_name = "prefetch_call";
- else if (fault_handler == fault_prefetch_abort)
- fault_name = "prefetch_abort";
- else if (fault_handler == fault_data_abort)
- fault_name = "data_abort";
- else
- fault_name = "unknown fault type!";
-
- printk("Fault handler at %p called (%s)\n", fault_handler, fault_name);
-
- for (i = 0; i < 16; i++) {
- printk("r%d = %x\n", i, saved_registers[i]);
- }
- printk("CPSR = %x\n", saved_registers[16]);
-
- printk("Stack dump (innermost last)\n");
- sp = (int *) saved_registers[13];
-
- if (sp >= _boot_stack && sp <= _boot_stack_end)
- stack_top = _boot_stack_end; /* The boot stack */
- else if (sp >= irqstack && sp <= irqstack_end)
- stack_top = irqstack_end; /* The IRQ stack */
- else
- stack_top = (int *) ((((unsigned long) sp) | (__STACK_SIZE-1)) + 1); /* A normal thread stack */
-
- for (x = stack_top - 1; x >= sp; x--)
- {
- printk(" [%8p] %8x\n", x, *x);
- }
- printk("End of stack\n");
-
- in_dump = 0;
-}
+++ /dev/null
-#include <mini-os/sched.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/console.h>
-
-void arm_start_thread(void);
-
-/* The AAPCS requires the callee (e.g. __arch_switch_threads) to preserve r4-r11. */
-#define CALLEE_SAVED_REGISTERS 8
-
-/* Architecture specific setup of thread creation */
-struct thread* arch_create_thread(char *name, void (*function)(void *),
- void *data)
-{
- struct thread *thread;
-
- thread = xmalloc(struct thread);
- /* We can't use lazy allocation here since the trap handler runs on the stack */
- thread->stack = (char *)alloc_pages(STACK_SIZE_PAGE_ORDER);
- thread->name = name;
- printk("Thread \"%s\": pointer: 0x%p, stack: 0x%p\n", name, thread,
- thread->stack);
-
- /* Save pointer to the thread on the stack, used by current macro */
- *((unsigned long *)thread->stack) = (unsigned long)thread;
-
- /* Push the details to pass to arm_start_thread onto the stack. */
- int *sp = (int *) (thread->stack + STACK_SIZE);
- *(--sp) = (int) function;
- *(--sp) = (int) data;
-
- /* We leave room for the 8 callee-saved registers which we will
- * try to restore on thread switch, even though they're not needed
- * for the initial switch. */
- thread->sp = (unsigned long) sp - 4 * CALLEE_SAVED_REGISTERS;
-
- thread->ip = (unsigned long) arm_start_thread;
-
- return thread;
-}
-
-void run_idle_thread(void)
-{
- __asm__ __volatile__ ("mov sp, %0; bx %1"::
- "r"(idle_thread->sp + 4 * CALLEE_SAVED_REGISTERS),
- "r"(idle_thread->ip));
- /* Never arrive here! */
-}
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/kernel.h>
-#include <mini-os/gic.h>
-#include <mini-os/console.h>
-#include <xen/xen.h>
-#include <xen/memory.h>
-#include <xen/hvm/params.h>
-#include <arch_mm.h>
-#include <libfdt.h>
-
-/*
- * This structure contains start-of-day info, such as pagetable base pointer,
- * address of the shared_info structure, and things like that.
- * On x86, the hypervisor passes it to us. On ARM, we fill it in ourselves.
- */
-union start_info_union start_info_union;
-
-/*
- * Shared page for communicating with the hypervisor.
- * Events flags go here, for example.
- */
-shared_info_t *HYPERVISOR_shared_info;
-
-extern char shared_info_page[PAGE_SIZE];
-
-void *device_tree;
-
-static int hvm_get_parameter(int idx, uint64_t *value)
-{
- struct xen_hvm_param xhv;
- int ret;
-
- xhv.domid = DOMID_SELF;
- xhv.index = idx;
- ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
- if (ret < 0) {
- BUG();
- }
- *value = xhv.value;
- return ret;
-}
-
-static void get_console(void)
-{
- uint64_t v = -1;
-
- hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
- start_info.console.domU.evtchn = v;
-
- hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
- start_info.console.domU.mfn = v;
-
- printk("Console is on port %d\n", start_info.console.domU.evtchn);
- printk("Console ring is at mfn %lx\n", (unsigned long) start_info.console.domU.mfn);
-}
-
-void get_xenbus(void)
-{
- uint64_t value;
-
- if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &value))
- BUG();
-
- start_info.store_evtchn = (int)value;
-
- if(hvm_get_parameter(HVM_PARAM_STORE_PFN, &value))
- BUG();
- start_info.store_mfn = (unsigned long)value;
-}
-
-/*
- * INITIAL C ENTRY POINT.
- */
-void arch_init(void *dtb_pointer, uint32_t physical_offset)
-{
- struct xen_add_to_physmap xatp;
- int r;
-
- memset(&__bss_start, 0, &_end - &__bss_start);
-
- physical_address_offset = physical_offset;
-
- xprintk("Virtual -> physical offset = %x\n", physical_address_offset);
-
- xprintk("Checking DTB at %p...\n", dtb_pointer);
-
- if ((r = fdt_check_header(dtb_pointer))) {
- xprintk("Invalid DTB from Xen: %s\n", fdt_strerror(r));
- BUG();
- }
- device_tree = dtb_pointer;
-
- /* Map shared_info page */
- xatp.domid = DOMID_SELF;
- xatp.idx = 0;
- xatp.space = XENMAPSPACE_shared_info;
- xatp.gpfn = virt_to_pfn(shared_info_page);
- if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
- BUG();
- HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
-
- /* Fill in start_info */
- get_console();
- get_xenbus();
-
- gic_init();
-
- start_kernel();
-}
-
-void
-arch_fini(void)
-{
-}
-
-void
-arch_do_exit(void)
-{
-}
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/traps.h>
-#include <mini-os/types.h>
-#include <mini-os/time.h>
-#include <mini-os/lib.h>
-
-//#define VTIMER_DEBUG
-#ifdef VTIMER_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=vtimer.c, line=%d) " _f , __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-/************************************************************************
- * Time functions
- *************************************************************************/
-
-static uint64_t cntvct_at_init;
-static uint32_t counter_freq;
-
-/* Compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
- uint32_t low, high;
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
-static inline s_time_t ticks_to_ns(uint64_t ticks)
-{
- return muldiv64(ticks, SECONDS(1), counter_freq);
-}
-
-static inline uint64_t ns_to_ticks(s_time_t ns)
-{
- return muldiv64(ns, counter_freq, SECONDS(1));
-}
-
-/* Wall-clock time is not currently available on ARM, so this is always zero for now:
- * http://wiki.xenproject.org/wiki/Xen_ARM_TODO#Expose_Wallclock_time_to_guests
- */
-static struct timespec shadow_ts;
-
-static inline uint64_t read_virtual_count(void)
-{
- uint32_t c_lo, c_hi;
- __asm__ __volatile__("mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
- return (((uint64_t) c_hi) << 32) + c_lo;
-}
-
-/* monotonic_clock(): returns # of nanoseconds passed since time_init()
- * Note: This function is required to return accurate
- * time even in the absence of multiple timer ticks.
- */
-uint64_t monotonic_clock(void)
-{
- return ticks_to_ns(read_virtual_count() - cntvct_at_init);
-}
-
-int gettimeofday(struct timeval *tv, void *tz)
-{
- uint64_t nsec = monotonic_clock();
- nsec += shadow_ts.tv_nsec;
-
- tv->tv_sec = shadow_ts.tv_sec;
- tv->tv_sec += NSEC_TO_SEC(nsec);
- tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL);
-
- return 0;
-}
-
-/* Set the timer and mask. */
-void write_timer_ctl(uint32_t value) {
- __asm__ __volatile__(
- "mcr p15, 0, %0, c14, c3, 1\n"
- "isb"::"r"(value));
-}
-
-void set_vtimer_compare(uint64_t value) {
- DEBUG("New CompareValue : %llx\n", value);
-
- __asm__ __volatile__("mcrr p15, 3, %0, %H0, c14"
- ::"r"(value));
-
- /* Enable timer and unmask the output signal */
- write_timer_ctl(1);
-}
-
-void unset_vtimer_compare(void) {
- /* Disable timer and mask the output signal */
- write_timer_ctl(2);
-}
-
-void block_domain(s_time_t until)
-{
- uint64_t until_count = ns_to_ticks(until) + cntvct_at_init;
- ASSERT(irqs_disabled());
- if (read_virtual_count() < until_count)
- {
- set_vtimer_compare(until_count);
- __asm__ __volatile__("wfi");
- unset_vtimer_compare();
-
- /* Give the IRQ handler a chance to handle whatever woke us up. */
- local_irq_enable();
- local_irq_disable();
- }
-}
-
-void init_time(void)
-{
- printk("Initialising timer interface\n");
-
- __asm__ __volatile__("mrc p15, 0, %0, c14, c0, 0":"=r"(counter_freq));
- cntvct_at_init = read_virtual_count();
- printk("Virtual Count register is %llx, freq = %d Hz\n", cntvct_at_init, counter_freq);
-}
-
-void fini_time(void)
-{
-}
+++ /dev/null
-#
-# x86 architecture specific makefiles.
-# It's is used for x86_32, x86_32y and x86_64
-#
-
-TOPLEVEL_DIR = $(CURDIR)/../..
-include ../../Config.mk
-
-# include arch.mk has to be before mini-os.mk!
-
-include arch.mk
-include ../../minios.mk
-
-# Sources here are all *.c *.S without $(MINIOS_TARGET_ARCH).S
-# This is handled in $(HEAD_ARCH_OBJ)
-ARCH_SRCS := $(wildcard *.c)
-
-# The objects built from the sources.
-ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
-
-all: $(OBJ_DIR)/$(ARCH_LIB)
-
-# $(HEAD_ARCH_OBJ) is only build here, needed on linking
-# in ../../Makefile.
-$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
- $(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
-
-clean:
- rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
-
+++ /dev/null
-#
-# Architecture special makerules for x86 family
-# (including x86_32, x86_32y and x86_64).
-#
-
-ifeq ($(MINIOS_TARGET_ARCH),x86_32)
-ARCH_CFLAGS := -m32 -march=i686
-ARCH_LDFLAGS := -m elf_i386
-ARCH_ASFLAGS := -m32
-EXTRA_INC += $(TARGET_ARCH_FAM)/$(MINIOS_TARGET_ARCH)
-EXTRA_SRC += arch/$(EXTRA_INC)
-endif
-
-ifeq ($(MINIOS_TARGET_ARCH),x86_64)
-ARCH_CFLAGS := -m64 -mno-red-zone -fno-reorder-blocks
-ARCH_CFLAGS += -fno-asynchronous-unwind-tables
-ARCH_ASFLAGS := -m64
-ARCH_LDFLAGS := -m elf_x86_64
-EXTRA_INC += $(TARGET_ARCH_FAM)/$(MINIOS_TARGET_ARCH)
-EXTRA_SRC += arch/$(EXTRA_INC)
-endif
-
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/mm.h>
-#include <mini-os/events.h>
-
-#if defined(__x86_64__)
-char irqstack[2 * STACK_SIZE];
-
-static struct pda
-{
- int irqcount; /* offset 0 (used in x86_64.S) */
- char *irqstackptr; /* 8 */
-} cpu0_pda;
-#endif
-
-void arch_init_events(void)
-{
-#if defined(__x86_64__)
- asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
- wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
- cpu0_pda.irqcount = -1;
- cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
- & ~(STACK_SIZE - 1));
-#endif
-}
-
-void arch_unbind_ports(void)
-{
-}
-
-void arch_fini_events(void)
-{
-#if defined(__x86_64__)
- wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
-#endif
-}
+++ /dev/null
-/*
- * Copyright (C) 2009, Netronome Systems, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/mm.h>
-#include <mini-os/ioremap.h>
-
-/* Map a physical address range into virtual address space with provided
- * flags. Return a virtual address range it is mapped to. */
-static void *__do_ioremap(unsigned long phys_addr, unsigned long size,
- unsigned long prot)
-{
- unsigned long va;
- unsigned long mfns, mfn;
- unsigned long num_pages, offset;
-
- /* allow non page aligned addresses but for mapping we need to align them */
- offset = (phys_addr & ~PAGE_MASK);
- num_pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
- phys_addr &= PAGE_MASK;
- mfns = mfn = phys_addr >> PAGE_SHIFT;
-
- va = (unsigned long)map_frames_ex(&mfns, num_pages, 0, 1, 1,
- DOMID_IO, NULL, prot);
- return (void *)(va + offset);
-}
-
-void *ioremap(unsigned long phys_addr, unsigned long size)
-{
- return __do_ioremap(phys_addr, size, IO_PROT);
-}
-
-void *ioremap_nocache(unsigned long phys_addr, unsigned long size)
-{
- return __do_ioremap(phys_addr, size, IO_PROT_NOCACHE);
-}
-
-/* Un-map the io-remapped region. Currently no list of existing mappings is
- * maintained, so the caller has to supply the size */
-void iounmap(void *virt_addr, unsigned long size)
-{
- unsigned long num_pages;
- unsigned long va = (unsigned long)virt_addr;
-
- /* work out number of frames to unmap */
- num_pages = ((va & ~PAGE_MASK) + size + PAGE_SIZE - 1) / PAGE_SIZE;
-
- unmap_frames(va & PAGE_MASK, num_pages);
-}
-
-
-
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
+++ /dev/null
-#include <mini-os/iorw.h>
-
-void iowrite8(volatile void* addr, uint8_t val)
-{
- *((volatile uint8_t*)addr) = val;
-}
-void iowrite16(volatile void* addr, uint16_t val)
-{
- *((volatile uint16_t*)addr) = val;
-}
-void iowrite32(volatile void* addr, uint32_t val)
-{
- *((volatile uint32_t*)addr) = val;
-}
-void iowrite64(volatile void* addr, uint64_t val)
-{
- *((volatile uint64_t*)addr) = val;
-}
-
-uint8_t ioread8(volatile void* addr)
-{
- return *((volatile uint8_t*) addr);
-}
-uint16_t ioread16(volatile void* addr)
-{
- return *((volatile uint16_t*) addr);
-}
-uint32_t ioread32(volatile void* addr)
-{
- return *((volatile uint32_t*) addr);
-}
-uint64_t ioread64(volatile void* addr)
-{
- return *((volatile uint64_t*) addr);
-}
+++ /dev/null
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x0;
- _text = .; /* Text and read-only data */
- .text : {
- *(.text)
- *(.gnu.warning)
- } = 0x9090
-
- _etext = .; /* End of text section */
-
- .rodata : { *(.rodata) *(.rodata.*) }
- . = ALIGN(4096);
- _erodata = .;
-
- /* newlib initialization functions */
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
-
- .ctors : {
- __CTOR_LIST__ = .;
- *(.ctors)
- CONSTRUCTORS
- LONG(0)
- __CTOR_END__ = .;
- }
-
- .dtors : {
- __DTOR_LIST__ = .;
- *(.dtors)
- LONG(0)
- __DTOR_END__ = .;
- }
-
- .data : { /* Data */
- *(.data)
- }
-
- _edata = .; /* End of data section */
-
- __bss_start = .; /* BSS */
- .bss : {
- *(.bss)
- *(.app.bss)
- }
- _end = . ;
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.text.exit)
- *(.data.exit)
- *(.exitcall.exit)
- }
-
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
-}
+++ /dev/null
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x0;
- _text = .; /* Text and read-only data */
- .text : {
- *(.text)
- *(.gnu.warning)
- } = 0x9090
-
- _etext = .; /* End of text section */
-
- .rodata : { *(.rodata) *(.rodata.*) }
- . = ALIGN(4096);
- _erodata = .;
-
- /* newlib initialization functions */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
-
- .ctors : {
- __CTOR_LIST__ = .;
- *(.ctors)
- CONSTRUCTORS
- QUAD(0)
- __CTOR_END__ = .;
- }
-
- .dtors : {
- __DTOR_LIST__ = .;
- *(.dtors)
- QUAD(0)
- __DTOR_END__ = .;
- }
-
- .data : { /* Data */
- *(.data)
- }
-
- _edata = .; /* End of data section */
-
- __bss_start = .; /* BSS */
- .bss : {
- *(.bss)
- *(.app.bss)
- }
- _end = . ;
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.text.exit)
- *(.data.exit)
- *(.exitcall.exit)
- }
-
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
-}
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: mm.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos
- *
- * Date: Aug 2003, chages Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: memory management related functions
- * contains buddy page allocator from Xen.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/mm.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-#include <xen/memory.h>
-
-#ifdef MM_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-unsigned long *phys_to_machine_mapping;
-unsigned long mfn_zero;
-extern char stack[];
-extern void page_walk(unsigned long va);
-
-/*
- * Make pt_pfn a new 'level' page table frame and hook it into the page
- * table at offset in previous level MFN (pref_l_mfn). pt_pfn is a guest
- * PFN.
- */
-static void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
- unsigned long offset, unsigned long level)
-{
- pgentry_t *tab = (pgentry_t *)start_info.pt_base;
- unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
- pgentry_t prot_e, prot_t;
- mmu_update_t mmu_updates[1];
- int rc;
-
- prot_e = prot_t = 0;
- DEBUG("Allocating new L%d pt frame for pfn=%lx, "
- "prev_l_mfn=%lx, offset=%lx",
- level, *pt_pfn, prev_l_mfn, offset);
-
- /* We need to clear the page, otherwise we might fail to map it
- as a page table page */
- memset((void*) pt_page, 0, PAGE_SIZE);
-
- switch ( level )
- {
- case L1_FRAME:
- prot_e = L1_PROT;
- prot_t = L2_PROT;
- break;
- case L2_FRAME:
- prot_e = L2_PROT;
- prot_t = L3_PROT;
- break;
-#if defined(__x86_64__)
- case L3_FRAME:
- prot_e = L3_PROT;
- prot_t = L4_PROT;
- break;
-#endif
- default:
- printk("new_pt_frame() called with invalid level number %d\n", level);
- do_exit();
- break;
- }
-
- /* Make PFN a page table page */
-#if defined(__x86_64__)
- tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
-#endif
- tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
-
- mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) +
- sizeof(pgentry_t) * l1_table_offset(pt_page);
- mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
- (prot_e & ~_PAGE_RW);
-
- if ( (rc = HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF)) < 0 )
- {
- printk("ERROR: PTE for new page table page could not be updated\n");
- printk(" mmu_update failed with rc=%d\n", rc);
- do_exit();
- }
-
- /* Hook the new page table page into the hierarchy */
- mmu_updates[0].ptr =
- ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
- mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
-
- if ( (rc = HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF)) < 0 )
- {
- printk("ERROR: mmu_update failed with rc=%d\n", rc);
- do_exit();
- }
-
- *pt_pfn += 1;
-}
-
-/*
- * Checks if a pagetable frame is needed at 'level' to map a given
- * address. Note, this function is specific to the initial page table
- * building.
- */
-static int need_pt_frame(unsigned long va, int level)
-{
- unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
-#if defined(__x86_64__)
- unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
-#else
- unsigned long hyp_virt_end = 0xffffffff;
-#endif
-
- /* In general frames will _not_ be needed if they were already
- allocated to map the hypervisor into our VA space */
-#if defined(__x86_64__)
- if ( level == L3_FRAME )
- {
- if ( l4_table_offset(va) >=
- l4_table_offset(hyp_virt_start) &&
- l4_table_offset(va) <=
- l4_table_offset(hyp_virt_end))
- return 0;
- return 1;
- }
- else
-#endif
-
- if ( level == L2_FRAME )
- {
-#if defined(__x86_64__)
- if ( l4_table_offset(va) >=
- l4_table_offset(hyp_virt_start) &&
- l4_table_offset(va) <=
- l4_table_offset(hyp_virt_end))
-#endif
- if ( l3_table_offset(va) >=
- l3_table_offset(hyp_virt_start) &&
- l3_table_offset(va) <=
- l3_table_offset(hyp_virt_end))
- return 0;
-
- return 1;
- }
- else
- /* Always need l1 frames */
- if ( level == L1_FRAME )
- return 1;
-
- printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n",
- level, hyp_virt_start, hyp_virt_end);
- return -1;
-}
-
-/*
- * Build the initial pagetable.
- */
-static void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
-{
- unsigned long start_address, end_address;
- unsigned long pfn_to_map, pt_pfn = *start_pfn;
- static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
- unsigned long offset;
- int count = 0;
- int rc;
-
- pfn_to_map =
- (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
-
- if ( *max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START) )
- {
- printk("WARNING: Mini-OS trying to use Xen virtual space. "
- "Truncating memory from %dMB to ",
- ((unsigned long)pfn_to_virt(*max_pfn) -
- (unsigned long)&_text)>>20);
- *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
- printk("%dMB\n",
- ((unsigned long)pfn_to_virt(*max_pfn) -
- (unsigned long)&_text)>>20);
- }
-
- start_address = (unsigned long)pfn_to_virt(pfn_to_map);
- end_address = (unsigned long)pfn_to_virt(*max_pfn);
-
- /* We worked out the virtual memory range to map, now mapping loop */
- printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
-
- while ( start_address < end_address )
- {
- tab = (pgentry_t *)start_info.pt_base;
- pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
-
-#if defined(__x86_64__)
- offset = l4_table_offset(start_address);
- /* Need new L3 pt frame */
- if ( !(start_address & L3_MASK) )
- if ( need_pt_frame(start_address, L3_FRAME) )
- new_pt_frame(&pt_pfn, pt_mfn, offset, L3_FRAME);
-
- page = tab[offset];
- pt_mfn = pte_to_mfn(page);
- tab = to_virt(mfn_to_pfn(pt_mfn) << PAGE_SHIFT);
-#endif
- offset = l3_table_offset(start_address);
- /* Need new L2 pt frame */
- if ( !(start_address & L2_MASK) )
- if ( need_pt_frame(start_address, L2_FRAME) )
- new_pt_frame(&pt_pfn, pt_mfn, offset, L2_FRAME);
-
- page = tab[offset];
- pt_mfn = pte_to_mfn(page);
- tab = to_virt(mfn_to_pfn(pt_mfn) << PAGE_SHIFT);
- offset = l2_table_offset(start_address);
- /* Need new L1 pt frame */
- if ( !(start_address & L1_MASK) )
- if ( need_pt_frame(start_address, L1_FRAME) )
- new_pt_frame(&pt_pfn, pt_mfn, offset, L1_FRAME);
-
- page = tab[offset];
- pt_mfn = pte_to_mfn(page);
- offset = l1_table_offset(start_address);
-
- mmu_updates[count].ptr =
- ((pgentry_t)pt_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
- mmu_updates[count].val =
- (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
- count++;
- if ( count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn )
- {
- rc = HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF);
- if ( rc < 0 )
- {
- printk("ERROR: build_pagetable(): PTE could not be updated\n");
- printk(" mmu_update failed with rc=%d\n", rc);
- do_exit();
- }
- count = 0;
- }
- start_address += PAGE_SIZE;
- }
-
- *start_pfn = pt_pfn;
-}
-
-/*
- * Mark portion of the address space read only.
- */
-extern struct shared_info shared_info;
-static void set_readonly(void *text, void *etext)
-{
- unsigned long start_address =
- ((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK;
- unsigned long end_address = (unsigned long) etext;
- static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
- unsigned long offset;
- int count = 0;
- int rc;
-
- printk("setting %p-%p readonly\n", text, etext);
-
- while ( start_address + PAGE_SIZE <= end_address )
- {
- tab = (pgentry_t *)start_info.pt_base;
- mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
-
-#if defined(__x86_64__)
- offset = l4_table_offset(start_address);
- page = tab[offset];
- mfn = pte_to_mfn(page);
- tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
-#endif
- offset = l3_table_offset(start_address);
- page = tab[offset];
- mfn = pte_to_mfn(page);
- tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
- offset = l2_table_offset(start_address);
- page = tab[offset];
- mfn = pte_to_mfn(page);
- tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
-
- offset = l1_table_offset(start_address);
-
- if ( start_address != (unsigned long)&shared_info )
- {
- mmu_updates[count].ptr =
- ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
- mmu_updates[count].val = tab[offset] & ~_PAGE_RW;
- count++;
- }
- else
- printk("skipped %p\n", start_address);
-
- start_address += PAGE_SIZE;
-
- if ( count == L1_PAGETABLE_ENTRIES ||
- start_address + PAGE_SIZE > end_address )
- {
- rc = HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF);
- if ( rc < 0 )
- {
- printk("ERROR: set_readonly(): PTE could not be updated\n");
- do_exit();
- }
- count = 0;
- }
- }
-
- {
- mmuext_op_t op = {
- .cmd = MMUEXT_TLB_FLUSH_ALL,
- };
- int count;
- HYPERVISOR_mmuext_op(&op, 1, &count, DOMID_SELF);
- }
-}
-
-/*
- * A useful mem testing function. Write the address to every address in the
- * range provided and read back the value. If verbose, print page walk to
- * some VA
- *
- * If we get MEM_TEST_MAX_ERRORS we might as well stop
- */
-#define MEM_TEST_MAX_ERRORS 10
-int mem_test(unsigned long *start_va, unsigned long *end_va, int verbose)
-{
- unsigned long mask = 0x10000;
- unsigned long *pointer;
- int error_count = 0;
-
- /* write values and print page walks */
- if ( verbose && (((unsigned long)start_va) & 0xfffff) )
- {
- printk("MemTest Start: 0x%lx\n", start_va);
- page_walk((unsigned long)start_va);
- }
- for ( pointer = start_va; pointer < end_va; pointer++ )
- {
- if ( verbose && !(((unsigned long)pointer) & 0xfffff) )
- {
- printk("Writing to %lx\n", pointer);
- page_walk((unsigned long)pointer);
- }
- *pointer = (unsigned long)pointer & ~mask;
- }
- if ( verbose && (((unsigned long)end_va) & 0xfffff) )
- {
- printk("MemTest End: %lx\n", end_va-1);
- page_walk((unsigned long)end_va-1);
- }
-
- /* verify values */
- for ( pointer = start_va; pointer < end_va; pointer++ )
- {
- if ( ((unsigned long)pointer & ~mask) != *pointer )
- {
- printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
- (unsigned long)pointer, *pointer,
- ((unsigned long)pointer & ~mask));
- error_count++;
- if ( error_count >= MEM_TEST_MAX_ERRORS )
- {
- printk("mem_test: too many errors\n");
- return -1;
- }
- }
- }
- return 0;
-}
-
-
-/*
- * get the PTE for virtual address va if it exists. Otherwise NULL.
- */
-static pgentry_t *get_pgt(unsigned long va)
-{
- unsigned long mfn;
- pgentry_t *tab;
- unsigned offset;
-
- tab = (pgentry_t *)start_info.pt_base;
- mfn = virt_to_mfn(start_info.pt_base);
-
-#if defined(__x86_64__)
- offset = l4_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- return NULL;
- mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(mfn);
-#endif
- offset = l3_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- return NULL;
- mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(mfn);
- offset = l2_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- return NULL;
- mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(mfn);
- offset = l1_table_offset(va);
- return &tab[offset];
-}
-
-
-/*
- * return a valid PTE for a given virtual address. If PTE does not exist,
- * allocate page-table pages.
- */
-pgentry_t *need_pgt(unsigned long va)
-{
- unsigned long pt_mfn;
- pgentry_t *tab;
- unsigned long pt_pfn;
- unsigned offset;
-
- tab = (pgentry_t *)start_info.pt_base;
- pt_mfn = virt_to_mfn(start_info.pt_base);
-
-#if defined(__x86_64__)
- offset = l4_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- {
- pt_pfn = virt_to_pfn(alloc_page());
- new_pt_frame(&pt_pfn, pt_mfn, offset, L3_FRAME);
- }
- ASSERT(tab[offset] & _PAGE_PRESENT);
- pt_mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(pt_mfn);
-#endif
- offset = l3_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- {
- pt_pfn = virt_to_pfn(alloc_page());
- new_pt_frame(&pt_pfn, pt_mfn, offset, L2_FRAME);
- }
- ASSERT(tab[offset] & _PAGE_PRESENT);
- pt_mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(pt_mfn);
- offset = l2_table_offset(va);
- if ( !(tab[offset] & _PAGE_PRESENT) )
- {
- pt_pfn = virt_to_pfn(alloc_page());
- new_pt_frame(&pt_pfn, pt_mfn, offset, L1_FRAME);
- }
- ASSERT(tab[offset] & _PAGE_PRESENT);
- pt_mfn = pte_to_mfn(tab[offset]);
- tab = mfn_to_virt(pt_mfn);
-
- offset = l1_table_offset(va);
- return &tab[offset];
-}
-
-/*
- * Reserve an area of virtual address space for mappings and Heap
- */
-static unsigned long demand_map_area_start;
-#ifdef __x86_64__
-#define DEMAND_MAP_PAGES ((128ULL << 30) / PAGE_SIZE)
-#else
-#define DEMAND_MAP_PAGES ((2ULL << 30) / PAGE_SIZE)
-#endif
-
-#ifndef HAVE_LIBC
-#define HEAP_PAGES 0
-#else
-unsigned long heap, brk, heap_mapped, heap_end;
-#ifdef __x86_64__
-#define HEAP_PAGES ((128ULL << 30) / PAGE_SIZE)
-#else
-#define HEAP_PAGES ((1ULL << 30) / PAGE_SIZE)
-#endif
-#endif
-
-void arch_init_demand_mapping_area(unsigned long cur_pfn)
-{
- cur_pfn++;
-
- demand_map_area_start = (unsigned long) pfn_to_virt(cur_pfn);
- cur_pfn += DEMAND_MAP_PAGES;
- printk("Demand map pfns at %lx-%lx.\n",
- demand_map_area_start, pfn_to_virt(cur_pfn));
-
-#ifdef HAVE_LIBC
- cur_pfn++;
- heap_mapped = brk = heap = (unsigned long) pfn_to_virt(cur_pfn);
- cur_pfn += HEAP_PAGES;
- heap_end = (unsigned long) pfn_to_virt(cur_pfn);
- printk("Heap resides at %lx-%lx.\n", brk, heap_end);
-#endif
-}
-
-unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
-{
- unsigned long x;
- unsigned long y = 0;
-
- /* Find a properly aligned run of n contiguous frames */
- for ( x = 0;
- x <= DEMAND_MAP_PAGES - n;
- x = (x + y + 1 + alignment - 1) & ~(alignment - 1) )
- {
- unsigned long addr = demand_map_area_start + x * PAGE_SIZE;
- pgentry_t *pgt = get_pgt(addr);
- for ( y = 0; y < n; y++, addr += PAGE_SIZE )
- {
- if ( !(addr & L1_MASK) )
- pgt = get_pgt(addr);
- if ( pgt )
- {
- if ( *pgt & _PAGE_PRESENT )
- break;
- pgt++;
- }
- }
- if ( y == n )
- break;
- }
- if ( y != n )
- {
- printk("Failed to find %ld frames!\n", n);
- return 0;
- }
- return demand_map_area_start + x * PAGE_SIZE;
-}
-
-/*
- * Map an array of MFNs contiguously into virtual address space starting at
- * va. map f[i*stride]+i*increment for i in 0..n-1.
- */
-#define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t))
-void do_map_frames(unsigned long va,
- const unsigned long *mfns, unsigned long n,
- unsigned long stride, unsigned long incr,
- domid_t id, int *err, unsigned long prot)
-{
- pgentry_t *pgt = NULL;
- unsigned long done = 0;
- unsigned long i;
- int rc;
-
- if ( !mfns )
- {
- printk("do_map_frames: no mfns supplied\n");
- return;
- }
- DEBUG("va=%p n=0x%lx, mfns[0]=0x%lx stride=0x%lx incr=0x%lx prot=0x%lx\n",
- va, n, mfns[0], stride, incr, prot);
-
- if ( err )
- memset(err, 0x00, n * sizeof(int));
- while ( done < n )
- {
- unsigned long todo;
-
- if ( err )
- todo = 1;
- else
- todo = n - done;
-
- if ( todo > MAP_BATCH )
- todo = MAP_BATCH;
-
- {
- mmu_update_t mmu_updates[todo];
-
- for ( i = 0; i < todo; i++, va += PAGE_SIZE, pgt++)
- {
- if ( !pgt || !(va & L1_MASK) )
- pgt = need_pgt(va);
-
- mmu_updates[i].ptr = virt_to_mach(pgt) | MMU_NORMAL_PT_UPDATE;
- mmu_updates[i].val = ((pgentry_t)(mfns[(done + i) * stride] +
- (done + i) * incr)
- << PAGE_SHIFT) | prot;
- }
-
- rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
- if ( rc < 0 )
- {
- if (err)
- err[done * stride] = rc;
- else {
- printk("Map %ld (%lx, ...) at %p failed: %d.\n",
- todo, mfns[done * stride] + done * incr, va, rc);
- do_exit();
- }
- }
- }
- done += todo;
- }
-}
-
-/*
- * Map an array of MFNs contiguous into virtual address space. Virtual
- * addresses are allocated from the on demand area.
- */
-void *map_frames_ex(const unsigned long *mfns, unsigned long n,
- unsigned long stride, unsigned long incr,
- unsigned long alignment,
- domid_t id, int *err, unsigned long prot)
-{
- unsigned long va = allocate_ondemand(n, alignment);
-
- if ( !va )
- return NULL;
-
- do_map_frames(va, mfns, n, stride, incr, id, err, prot);
-
- return (void *)va;
-}
-
-/*
- * Unmap nun_frames frames mapped at virtual address va.
- */
-#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
-int unmap_frames(unsigned long va, unsigned long num_frames)
-{
- int n = UNMAP_BATCH;
- multicall_entry_t call[n];
- int ret;
- int i;
-
- ASSERT(!((unsigned long)va & ~PAGE_MASK));
-
- DEBUG("va=%p, num=0x%lx\n", va, num_frames);
-
- while ( num_frames ) {
- if ( n > num_frames )
- n = num_frames;
-
- for ( i = 0; i < n; i++ )
- {
- int arg = 0;
- /* simply update the PTE for the VA and invalidate TLB */
- call[i].op = __HYPERVISOR_update_va_mapping;
- call[i].args[arg++] = va;
- call[i].args[arg++] = 0;
-#ifdef __i386__
- call[i].args[arg++] = 0;
-#endif
- call[i].args[arg++] = UVMF_INVLPG;
-
- va += PAGE_SIZE;
- }
-
- ret = HYPERVISOR_multicall(call, n);
- if ( ret )
- {
- printk("update_va_mapping hypercall failed with rc=%d.\n", ret);
- return -ret;
- }
-
- for ( i = 0; i < n; i++ )
- {
- if ( call[i].result )
- {
- printk("update_va_mapping failed for with rc=%d.\n", ret);
- return -(call[i].result);
- }
- }
- num_frames -= n;
- }
- return 0;
-}
-
-/*
- * Allocate pages which are contiguous in machine memory.
- * Returns a VA to where they are mapped or 0 on failure.
- *
- * addr_bits indicates if the region has restrictions on where it is
- * located. Typical values are 32 (if for example PCI devices can't access
- * 64bit memory) or 0 for no restrictions.
- *
- * Allocated pages can be freed using the page allocators free_pages()
- * function.
- *
- * based on Linux function xen_create_contiguous_region()
- */
-#define MAX_CONTIG_ORDER 9 /* 2MB */
-unsigned long alloc_contig_pages(int order, unsigned int addr_bits)
-{
- unsigned long in_va, va;
- unsigned long in_frames[1UL << order], out_frames, mfn;
- multicall_entry_t call[1UL << order];
- unsigned int i, num_pages = 1UL << order;
- int ret, exch_success;
-
- /* pass in num_pages 'extends' of size 1 and
- * request 1 extend of size 'order */
- struct xen_memory_exchange exchange = {
- .in = {
- .nr_extents = num_pages,
- .extent_order = 0,
- .domid = DOMID_SELF
- },
- .out = {
- .nr_extents = 1,
- .extent_order = order,
- .address_bits = addr_bits,
- .domid = DOMID_SELF
- },
- .nr_exchanged = 0
- };
-
- if ( order > MAX_CONTIG_ORDER )
- {
- printk("alloc_contig_pages: order too large 0x%x > 0x%x\n",
- order, MAX_CONTIG_ORDER);
- return 0;
- }
-
- /* Allocate some potentially discontiguous pages */
- in_va = alloc_pages(order);
- if ( !in_va )
- {
- printk("alloc_contig_pages: could not get enough pages (order=0x%x\n",
- order);
- return 0;
- }
-
- /* set up arguments for exchange hyper call */
- set_xen_guest_handle(exchange.in.extent_start, in_frames);
- set_xen_guest_handle(exchange.out.extent_start, &out_frames);
-
- /* unmap current frames, keep a list of MFNs */
- for ( i = 0; i < num_pages; i++ )
- {
- int arg = 0;
-
- va = in_va + (PAGE_SIZE * i);
- in_frames[i] = virt_to_mfn(va);
-
- /* update P2M mapping */
- phys_to_machine_mapping[virt_to_pfn(va)] = INVALID_P2M_ENTRY;
-
- /* build multi call */
- call[i].op = __HYPERVISOR_update_va_mapping;
- call[i].args[arg++] = va;
- call[i].args[arg++] = 0;
-#ifdef __i386__
- call[i].args[arg++] = 0;
-#endif
- call[i].args[arg++] = UVMF_INVLPG;
- }
-
- ret = HYPERVISOR_multicall(call, i);
- if ( ret )
- {
- printk("Odd, update_va_mapping hypercall failed with rc=%d.\n", ret);
- return 0;
- }
-
- /* try getting a contig range of MFNs */
- out_frames = virt_to_pfn(in_va); /* PFNs to populate */
- ret = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
- if ( ret ) {
- printk("mem exchanged order=0x%x failed with rc=%d, nr_exchanged=%d\n",
- order, ret, exchange.nr_exchanged);
- /* we still need to return the allocated pages above to the pool
- * ie. map them back into the 1:1 mapping etc. so we continue but
- * in the end return the pages to the page allocator and return 0. */
- exch_success = 0;
- }
- else
- exch_success = 1;
-
- /* map frames into 1:1 and update p2m */
- for ( i = 0; i < num_pages; i++ )
- {
- int arg = 0;
- pte_t pte;
-
- va = in_va + (PAGE_SIZE * i);
- mfn = i < exchange.nr_exchanged ? (out_frames + i) : in_frames[i];
- pte = __pte(mfn << PAGE_SHIFT | L1_PROT);
-
- /* update P2M mapping */
- phys_to_machine_mapping[virt_to_pfn(va)] = mfn;
-
- /* build multi call */
- call[i].op = __HYPERVISOR_update_va_mapping;
- call[i].args[arg++] = va;
-#ifdef __x86_64__
- call[i].args[arg++] = (pgentry_t)pte.pte;
-#else
- call[i].args[arg++] = pte.pte_low;
- call[i].args[arg++] = pte.pte_high;
-#endif
- call[i].args[arg++] = UVMF_INVLPG;
- }
- ret = HYPERVISOR_multicall(call, i);
- if ( ret )
- {
- printk("update_va_mapping hypercall no. 2 failed with rc=%d.\n", ret);
- return 0;
- }
-
- if ( !exch_success )
- {
- /* since the exchanged failed we just free the pages as well */
- free_pages((void *) in_va, order);
- return 0;
- }
-
- return in_va;
-}
-
-/*
- * Clear some of the bootstrap memory
- */
-static void clear_bootstrap(void)
-{
- pte_t nullpte = { };
- int rc;
-
- /* Use first page as the CoW zero page */
- memset(&_text, 0, PAGE_SIZE);
- mfn_zero = virt_to_mfn((unsigned long) &_text);
- if ( (rc = HYPERVISOR_update_va_mapping(0, nullpte, UVMF_INVLPG)) )
- printk("Unable to unmap NULL page. rc=%d\n", rc);
-}
-
-void arch_init_p2m(unsigned long max_pfn)
-{
-#ifdef __x86_64__
-#define L1_P2M_SHIFT 9
-#define L2_P2M_SHIFT 18
-#define L3_P2M_SHIFT 27
-#else
-#define L1_P2M_SHIFT 10
-#define L2_P2M_SHIFT 20
-#define L3_P2M_SHIFT 30
-#endif
-#define L1_P2M_ENTRIES (1 << L1_P2M_SHIFT)
-#define L2_P2M_ENTRIES (1 << (L2_P2M_SHIFT - L1_P2M_SHIFT))
-#define L3_P2M_ENTRIES (1 << (L3_P2M_SHIFT - L2_P2M_SHIFT))
-#define L1_P2M_MASK (L1_P2M_ENTRIES - 1)
-#define L2_P2M_MASK (L2_P2M_ENTRIES - 1)
-#define L3_P2M_MASK (L3_P2M_ENTRIES - 1)
-
- unsigned long *l1_list = NULL, *l2_list = NULL, *l3_list;
- unsigned long pfn;
-
- l3_list = (unsigned long *)alloc_page();
- for ( pfn=0; pfn<max_pfn; pfn++ )
- {
- if ( !(pfn % (L1_P2M_ENTRIES * L2_P2M_ENTRIES)) )
- {
- l2_list = (unsigned long*)alloc_page();
- if ( (pfn >> L3_P2M_SHIFT) > 0 )
- {
- printk("Error: Too many pfns.\n");
- do_exit();
- }
- l3_list[(pfn >> L2_P2M_SHIFT)] = virt_to_mfn(l2_list);
- }
- if ( !(pfn % (L1_P2M_ENTRIES)) )
- {
- l1_list = (unsigned long*)alloc_page();
- l2_list[(pfn >> L1_P2M_SHIFT) & L2_P2M_MASK] =
- virt_to_mfn(l1_list);
- }
-
- l1_list[pfn & L1_P2M_MASK] = pfn_to_mfn(pfn);
- }
- HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
- virt_to_mfn(l3_list);
- HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-}
-
-void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
-{
- unsigned long start_pfn, max_pfn;
-
- printk(" _text: %p(VA)\n", &_text);
- printk(" _etext: %p(VA)\n", &_etext);
- printk(" _erodata: %p(VA)\n", &_erodata);
- printk(" _edata: %p(VA)\n", &_edata);
- printk("stack start: %p(VA)\n", stack);
- printk(" _end: %p(VA)\n", &_end);
-
- /* First page follows page table pages and 3 more pages (store page etc) */
- start_pfn = PFN_UP(to_phys(start_info.pt_base)) +
- start_info.nr_pt_frames + 3;
- max_pfn = start_info.nr_pages;
-
- /* We need room for demand mapping and heap, clip available memory */
-#if defined(__i386__)
- {
- unsigned long virt_pfns = 1 + DEMAND_MAP_PAGES + 1 + HEAP_PAGES;
- if (max_pfn + virt_pfns >= 0x100000)
- max_pfn = 0x100000 - virt_pfns - 1;
- }
-#endif
-
- printk(" start_pfn: %lx\n", start_pfn);
- printk(" max_pfn: %lx\n", max_pfn);
-
- build_pagetable(&start_pfn, &max_pfn);
- clear_bootstrap();
- set_readonly(&_text, &_erodata);
-
- *start_pfn_p = start_pfn;
- *max_pfn_p = max_pfn;
-}
-
-grant_entry_t *arch_init_gnttab(int nr_grant_frames)
-{
- struct gnttab_setup_table setup;
- unsigned long frames[nr_grant_frames];
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = nr_grant_frames;
- set_xen_guest_handle(setup.frame_list, frames);
-
- HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- return map_frames(frames, nr_grant_frames);
-}
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: sched.c
- * Author: Grzegorz Milos
- * Changes: Robert Kaiser
- *
- * Date: Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/time.h>
-#include <mini-os/mm.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/list.h>
-#include <mini-os/sched.h>
-#include <mini-os/semaphore.h>
-
-
-#ifdef SCHED_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-
-void dump_stack(struct thread *thread)
-{
- unsigned long *bottom = (unsigned long *)(thread->stack + STACK_SIZE);
- unsigned long *pointer = (unsigned long *)thread->sp;
- int count;
- if(thread == current)
- {
-#ifdef __i386__
- asm("movl %%esp,%0"
- : "=r"(pointer));
-#else
- asm("movq %%rsp,%0"
- : "=r"(pointer));
-#endif
- }
- printk("The stack for \"%s\"\n", thread->name);
- for(count = 0; count < 25 && pointer < bottom; count ++)
- {
- printk("[0x%lx] 0x%lx\n", pointer, *pointer);
- pointer++;
- }
-
- if(pointer < bottom) printk(" ... continues.\n");
-}
-
-/* Gets run when a new thread is scheduled the first time ever,
- defined in x86_[32/64].S */
-extern void thread_starter(void);
-
-/* Pushes the specified value onto the stack of the specified thread */
-static void stack_push(struct thread *thread, unsigned long value)
-{
- thread->sp -= sizeof(unsigned long);
- *((unsigned long *)thread->sp) = value;
-}
-
-/* Architecture specific setup of thread creation */
-struct thread* arch_create_thread(char *name, void (*function)(void *),
- void *data)
-{
- struct thread *thread;
-
- thread = xmalloc(struct thread);
- /* We can't use lazy allocation here since the trap handler runs on the stack */
- thread->stack = (char *)alloc_pages(STACK_SIZE_PAGE_ORDER);
- thread->name = name;
- printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
- thread->stack);
-
- thread->sp = (unsigned long)thread->stack + STACK_SIZE;
- /* Save pointer to the thread on the stack, used by current macro */
- *((unsigned long *)thread->stack) = (unsigned long)thread;
-
- /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */
- thread->sp -= sizeof(unsigned long);
-
- stack_push(thread, (unsigned long) function);
- stack_push(thread, (unsigned long) data);
- thread->ip = (unsigned long) thread_starter;
- return thread;
-}
-
-void run_idle_thread(void)
-{
- /* Switch stacks and run the thread */
-#if defined(__i386__)
- __asm__ __volatile__("mov %0,%%esp\n\t"
- "push %1\n\t"
- "ret"
- :"=m" (idle_thread->sp)
- :"m" (idle_thread->ip));
-#elif defined(__x86_64__)
- __asm__ __volatile__("mov %0,%%rsp\n\t"
- "push %1\n\t"
- "ret"
- :"=m" (idle_thread->sp)
- :"m" (idle_thread->ip));
-#endif
-}
-
-
-
+++ /dev/null
-/******************************************************************************
- * common.c
- *
- * Common stuff special to x86 goes here.
- *
- * Copyright (c) 2002-2003, K A Fraser & R Neugebauer
- * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <mini-os/os.h>
-#include <mini-os/lib.h> /* for printk, memcpy */
-#include <mini-os/kernel.h>
-#include <xen/xen.h>
-
-/*
- * Shared page for communicating with the hypervisor.
- * Events flags go here, for example.
- */
-shared_info_t *HYPERVISOR_shared_info;
-
-/*
- * This structure contains start-of-day info, such as pagetable base pointer,
- * address of the shared_info structure, and things like that.
- */
-union start_info_union start_info_union;
-
-/*
- * Just allocate the kernel stack here. SS:ESP is set up to point here
- * in head.S.
- */
-char stack[2*STACK_SIZE];
-
-extern char shared_info[PAGE_SIZE];
-
-/* Assembler interface fns in entry.S. */
-void hypervisor_callback(void);
-void failsafe_callback(void);
-
-#if defined(__x86_64__)
-#define __pte(x) ((pte_t) { (x) } )
-#else
-#define __pte(x) ({ unsigned long long _x = (x); \
- ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
-#endif
-
-static
-shared_info_t *map_shared_info(unsigned long pa)
-{
- int rc;
-
- if ( (rc = HYPERVISOR_update_va_mapping(
- (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG)) )
- {
- printk("Failed to map shared_info!! rc=%d\n", rc);
- do_exit();
- }
- return (shared_info_t *)shared_info;
-}
-
-static inline void fpu_init(void) {
- asm volatile("fninit");
-}
-
-#ifdef __SSE__
-static inline void sse_init(void) {
- unsigned long status = 0x1f80;
- asm volatile("ldmxcsr %0" : : "m" (status));
-}
-#else
-#define sse_init()
-#endif
-
-
-/*
- * INITIAL C ENTRY POINT.
- */
-void
-arch_init(start_info_t *si)
-{
- static char hello[] = "Bootstrapping...\n";
-
- (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
-
- trap_init();
-
- /*Initialize floating point unit */
- fpu_init();
-
- /* Initialize SSE */
- sse_init();
-
- /* Copy the start_info struct to a globally-accessible area. */
- /* WARN: don't do printk before here, it uses information from
- shared_info. Use xprintk instead. */
- memcpy(&start_info, si, sizeof(*si));
-
- /* print out some useful information */
- printk("Xen Minimal OS!\n");
- printk(" start_info: %p(VA)\n", si);
- printk(" nr_pages: 0x%lx\n", si->nr_pages);
- printk(" shared_inf: 0x%08lx(MA)\n", si->shared_info);
- printk(" pt_base: %p(VA)\n", (void *)si->pt_base);
- printk("nr_pt_frames: 0x%lx\n", si->nr_pt_frames);
- printk(" mfn_list: %p(VA)\n", (void *)si->mfn_list);
- printk(" mod_start: 0x%lx(VA)\n", si->mod_start);
- printk(" mod_len: %lu\n", si->mod_len);
- printk(" flags: 0x%x\n", (unsigned int)si->flags);
- printk(" cmd_line: %s\n",
- si->cmd_line ? (const char *)si->cmd_line : "NULL");
- printk(" stack: %p-%p\n", stack, stack + sizeof(stack));
-
- /* set up minimal memory infos */
- phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
-
- /* Grab the shared_info pointer and put it in a safe place. */
- HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
-
- /* Set up event and failsafe callback addresses. */
-#ifdef __i386__
- HYPERVISOR_set_callbacks(
- __KERNEL_CS, (unsigned long)hypervisor_callback,
- __KERNEL_CS, (unsigned long)failsafe_callback);
-#else
- HYPERVISOR_set_callbacks(
- (unsigned long)hypervisor_callback,
- (unsigned long)failsafe_callback, 0);
-#endif
-
- start_kernel();
-}
-
-void
-arch_fini(void)
-{
- /* Reset traps */
- trap_fini();
-
-#ifdef __i386__
- HYPERVISOR_set_callbacks(0, 0, 0, 0);
-#else
- HYPERVISOR_set_callbacks(0, 0, 0);
-#endif
-}
-
-void
-arch_do_exit(void)
-{
- stack_walk();
-}
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2002-2003 - Keir Fraser - University of Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- * (C) 2006 - Robert Kaiser - FH Wiesbaden
- ****************************************************************************
- *
- * File: time.c
- * Author: Rolf Neugebauer and Keir Fraser
- * Changes: Grzegorz Milos
- *
- * Description: Simple time and timer functions
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#include <mini-os/os.h>
-#include <mini-os/traps.h>
-#include <mini-os/types.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/time.h>
-#include <mini-os/lib.h>
-
-/************************************************************************
- * Time functions
- *************************************************************************/
-
-/* These are peridically updated in shared_info, and then copied here. */
-struct shadow_time_info {
- uint64_t tsc_timestamp; /* TSC at last update of time vals. */
- uint64_t system_timestamp; /* Time, in nanosecs, since boot. */
- uint32_t tsc_to_nsec_mul;
- uint32_t tsc_to_usec_mul;
- int tsc_shift;
- uint32_t version;
-};
-static struct timespec shadow_ts;
-static uint32_t shadow_ts_version;
-
-static struct shadow_time_info shadow;
-
-
-#ifndef rmb
-#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
-#endif
-
-#define HANDLE_USEC_OVERFLOW(_tv) \
- do { \
- while ( (_tv)->tv_usec >= 1000000 ) \
- { \
- (_tv)->tv_usec -= 1000000; \
- (_tv)->tv_sec++; \
- } \
- } while ( 0 )
-
-static inline int time_values_up_to_date(void)
-{
- struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_info[0].time;
-
- return (shadow.version == src->version);
-}
-
-
-/*
- * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
- * yielding a 64-bit result.
- */
-static inline uint64_t scale_delta(uint64_t delta, uint32_t mul_frac, int shift)
-{
- uint64_t product;
-#ifdef __i386__
- uint32_t tmp1, tmp2;
-#endif
-
- if ( shift < 0 )
- delta >>= -shift;
- else
- delta <<= shift;
-
-#ifdef __i386__
- __asm__ (
- "mul %5 ; "
- "mov %4,%%eax ; "
- "mov %%edx,%4 ; "
- "mul %5 ; "
- "add %4,%%eax ; "
- "xor %5,%5 ; "
- "adc %5,%%edx ; "
- : "=A" (product), "=r" (tmp1), "=r" (tmp2)
- : "a" ((uint32_t)delta), "1" ((uint32_t)(delta >> 32)), "2" (mul_frac) );
-#else
- __asm__ (
- "mul %%rdx ; shrd $32,%%rdx,%%rax"
- : "=a" (product) : "0" (delta), "d" ((uint64_t)mul_frac) );
-#endif
-
- return product;
-}
-
-
-static unsigned long get_nsec_offset(void)
-{
- uint64_t now, delta;
- rdtscll(now);
- delta = now - shadow.tsc_timestamp;
- return scale_delta(delta, shadow.tsc_to_nsec_mul, shadow.tsc_shift);
-}
-
-
-static void get_time_values_from_xen(void)
-{
- struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_info[0].time;
-
- do {
- shadow.version = src->version;
- rmb();
- shadow.tsc_timestamp = src->tsc_timestamp;
- shadow.system_timestamp = src->system_time;
- shadow.tsc_to_nsec_mul = src->tsc_to_system_mul;
- shadow.tsc_shift = src->tsc_shift;
- rmb();
- }
- while ((src->version & 1) | (shadow.version ^ src->version));
-
- shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
-}
-
-
-
-
-/* monotonic_clock(): returns # of nanoseconds passed since time_init()
- * Note: This function is required to return accurate
- * time even in the absence of multiple timer ticks.
- */
-uint64_t monotonic_clock(void)
-{
- uint64_t time;
- uint32_t local_time_version;
-
- do {
- local_time_version = shadow.version;
- rmb();
- time = shadow.system_timestamp + get_nsec_offset();
- if (!time_values_up_to_date())
- get_time_values_from_xen();
- rmb();
- } while (local_time_version != shadow.version);
-
- return time;
-}
-
-static void update_wallclock(void)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
-
- do {
- shadow_ts_version = s->wc_version;
- rmb();
- shadow_ts.tv_sec = s->wc_sec;
- shadow_ts.tv_nsec = s->wc_nsec;
- rmb();
- }
- while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version));
-}
-
-
-int gettimeofday(struct timeval *tv, void *tz)
-{
- uint64_t nsec = monotonic_clock();
- nsec += shadow_ts.tv_nsec;
-
-
- tv->tv_sec = shadow_ts.tv_sec;
- tv->tv_sec += NSEC_TO_SEC(nsec);
- tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL);
-
- return 0;
-}
-
-
-void block_domain(s_time_t until)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- ASSERT(irqs_disabled());
- if(monotonic_clock() < until)
- {
- HYPERVISOR_set_timer_op(until);
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
- local_irq_disable();
- }
-}
-
-
-/*
- * Just a dummy
- */
-static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
-{
- get_time_values_from_xen();
- update_wallclock();
-}
-
-
-
-static evtchn_port_t port;
-void init_time(void)
-{
- printk("Initialising timer interface\n");
- port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
- unmask_evtchn(port);
-}
-
-void fini_time(void)
-{
- /* Clear any pending timer */
- HYPERVISOR_set_timer_op(0);
- unbind_evtchn(port);
-}
+++ /dev/null
-
-#include <mini-os/os.h>
-#include <mini-os/traps.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/mm.h>
-#include <mini-os/lib.h>
-#include <mini-os/sched.h>
-
-/*
- * These are assembler stubs in entry.S.
- * They are the actual entry points for virtual exceptions.
- */
-void divide_error(void);
-void debug(void);
-void int3(void);
-void overflow(void);
-void bounds(void);
-void invalid_op(void);
-void device_not_available(void);
-void coprocessor_segment_overrun(void);
-void invalid_TSS(void);
-void segment_not_present(void);
-void stack_segment(void);
-void general_protection(void);
-void page_fault(void);
-void coprocessor_error(void);
-void simd_coprocessor_error(void);
-void alignment_check(void);
-void spurious_interrupt_bug(void);
-void machine_check(void);
-
-
-void dump_regs(struct pt_regs *regs)
-{
- printk("Thread: %s\n", current->name);
-#ifdef __i386__
- printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
- printk("EBX: %08x ECX: %08x EDX: %08x\n",
- regs->ebx, regs->ecx, regs->edx);
- printk("ESI: %08x EDI: %08x EBP: %08x EAX: %08x\n",
- regs->esi, regs->edi, regs->ebp, regs->eax);
- printk("DS: %04x ES: %04x orig_eax: %08x, eip: %08x\n",
- regs->xds, regs->xes, regs->orig_eax, regs->eip);
- printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
- regs->xcs, regs->eflags, regs->esp, regs->xss);
-#else
- printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
- printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n",
- regs->ss, regs->rsp, regs->eflags);
- printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
- regs->rax, regs->rbx, regs->rcx);
- printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
- regs->rdx, regs->rsi, regs->rdi);
- printk("RBP: %016lx R08: %016lx R09: %016lx\n",
- regs->rbp, regs->r8, regs->r9);
- printk("R10: %016lx R11: %016lx R12: %016lx\n",
- regs->r10, regs->r11, regs->r12);
- printk("R13: %016lx R14: %016lx R15: %016lx\n",
- regs->r13, regs->r14, regs->r15);
-#endif
-}
-
-static void do_trap(int trapnr, char *str, struct pt_regs * regs, unsigned long error_code)
-{
- printk("FATAL: Unhandled Trap %d (%s), error code=0x%lx\n", trapnr, str, error_code);
- printk("Regs address %p\n", regs);
- dump_regs(regs);
- do_exit();
-}
-
-#define DO_ERROR(trapnr, str, name) \
-void do_##name(struct pt_regs * regs, unsigned long error_code) \
-{ \
- do_trap(trapnr, str, regs, error_code); \
-}
-
-#define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
-void do_##name(struct pt_regs * regs, unsigned long error_code) \
-{ \
- do_trap(trapnr, str, regs, error_code); \
-}
-
-DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
-DO_ERROR( 3, "int3", int3)
-DO_ERROR( 4, "overflow", overflow)
-DO_ERROR( 5, "bounds", bounds)
-DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
-DO_ERROR( 7, "device not available", device_not_available)
-DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
-DO_ERROR(10, "invalid TSS", invalid_TSS)
-DO_ERROR(11, "segment not present", segment_not_present)
-DO_ERROR(12, "stack segment", stack_segment)
-DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR(18, "machine check", machine_check)
-
-void page_walk(unsigned long virt_address)
-{
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long addr = virt_address;
- printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base);
-
-#if defined(__x86_64__)
- page = tab[l4_table_offset(addr)];
- tab = pte_to_virt(page);
- printk(" L4 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr));
-#endif
- page = tab[l3_table_offset(addr)];
- tab = pte_to_virt(page);
- printk(" L3 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr));
- page = tab[l2_table_offset(addr)];
- tab = pte_to_virt(page);
- printk(" L2 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr));
-
- page = tab[l1_table_offset(addr)];
- printk(" L1 = %"PRIpte" [offset = %lx]\n", page, l1_table_offset(addr));
-
-}
-
-static int handle_cow(unsigned long addr) {
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long new_page;
- int rc;
-
-#if defined(__x86_64__)
- page = tab[l4_table_offset(addr)];
- if (!(page & _PAGE_PRESENT))
- return 0;
- tab = pte_to_virt(page);
-#endif
- page = tab[l3_table_offset(addr)];
- if (!(page & _PAGE_PRESENT))
- return 0;
- tab = pte_to_virt(page);
-
- page = tab[l2_table_offset(addr)];
- if (!(page & _PAGE_PRESENT))
- return 0;
- tab = pte_to_virt(page);
-
- page = tab[l1_table_offset(addr)];
- if (!(page & _PAGE_PRESENT))
- return 0;
- /* Only support CoW for the zero page. */
- if (PHYS_PFN(page) != mfn_zero)
- return 0;
-
- new_page = alloc_pages(0);
- memset((void*) new_page, 0, PAGE_SIZE);
-
- rc = HYPERVISOR_update_va_mapping(addr & PAGE_MASK, __pte(virt_to_mach(new_page) | L1_PROT), UVMF_INVLPG);
- if (!rc)
- return 1;
-
- printk("Map zero page to %lx failed: %d.\n", addr, rc);
- return 0;
-}
-
-static void do_stack_walk(unsigned long frame_base)
-{
- unsigned long *frame = (void*) frame_base;
- printk("base is %#lx ", frame_base);
- printk("caller is %#lx\n", frame[1]);
- if (frame[0])
- do_stack_walk(frame[0]);
-}
-
-void stack_walk(void)
-{
- unsigned long bp;
-#ifdef __x86_64__
- asm("movq %%rbp, %0":"=r"(bp));
-#else
- asm("movl %%ebp, %0":"=r"(bp));
-#endif
- do_stack_walk(bp);
-}
-
-static void dump_mem(unsigned long addr)
-{
- unsigned long i;
- if (addr < PAGE_SIZE)
- return;
-
- for (i = ((addr)-16 ) & ~15; i < (((addr)+48 ) & ~15); i++)
- {
- if (!(i%16))
- printk("\n%lx:", i);
- printk(" %02x", *(unsigned char *)i);
- }
- printk("\n");
-}
-#define read_cr2() \
- (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
-
-static int handling_pg_fault = 0;
-
-void do_page_fault(struct pt_regs *regs, unsigned long error_code)
-{
- unsigned long addr = read_cr2();
- struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
-
- if ((error_code & TRAP_PF_WRITE) && handle_cow(addr))
- return;
-
- /* If we are already handling a page fault, and got another one
- that means we faulted in pagetable walk. Continuing here would cause
- a recursive fault */
- if(handling_pg_fault == 1)
- {
- printk("Page fault in pagetable walk (access to invalid memory?).\n");
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
- }
- handling_pg_fault++;
- barrier();
-
-#if defined(__x86_64__)
- printk("Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx\n",
- addr, regs->rip, regs, regs->rsp, &addr, error_code);
-#else
- printk("Page fault at linear address %p, eip %p, regs %p, sp %p, our_sp %p, code %lx\n",
- addr, regs->eip, regs, regs->esp, &addr, error_code);
-#endif
-
- dump_regs(regs);
-#if defined(__x86_64__)
- do_stack_walk(regs->rbp);
- dump_mem(regs->rsp);
- dump_mem(regs->rbp);
- dump_mem(regs->rip);
-#else
- do_stack_walk(regs->ebp);
- dump_mem(regs->esp);
- dump_mem(regs->ebp);
- dump_mem(regs->eip);
-#endif
- page_walk(addr);
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
- /* We should never get here ... but still */
- handling_pg_fault--;
-}
-
-void do_general_protection(struct pt_regs *regs, long error_code)
-{
- struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
-#ifdef __i386__
- printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
-#else
- printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
-#endif
- dump_regs(regs);
-#if defined(__x86_64__)
- do_stack_walk(regs->rbp);
- dump_mem(regs->rsp);
- dump_mem(regs->rbp);
- dump_mem(regs->rip);
-#else
- do_stack_walk(regs->ebp);
- dump_mem(regs->esp);
- dump_mem(regs->ebp);
- dump_mem(regs->eip);
-#endif
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-}
-
-
-void do_debug(struct pt_regs * regs)
-{
- printk("Debug exception\n");
-#define TF_MASK 0x100
- regs->eflags &= ~TF_MASK;
- dump_regs(regs);
- do_exit();
-}
-
-void do_coprocessor_error(struct pt_regs * regs)
-{
- printk("Copro error\n");
- dump_regs(regs);
- do_exit();
-}
-
-void simd_math_error(void *eip)
-{
- printk("SIMD error\n");
-}
-
-void do_simd_coprocessor_error(struct pt_regs * regs)
-{
- printk("SIMD copro error\n");
-}
-
-void do_spurious_interrupt_bug(struct pt_regs * regs)
-{
-}
-
-/*
- * Submit a virtual IDT to teh hypervisor. This consists of tuples
- * (interrupt vector, privilege ring, CS:EIP of handler).
- * The 'privilege ring' field specifies the least-privileged ring that
- * can trap to that vector using a software-interrupt instruction (INT).
- */
-static trap_info_t trap_table[] = {
- { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
- { 1, 0, __KERNEL_CS, (unsigned long)debug },
- { 3, 3, __KERNEL_CS, (unsigned long)int3 },
- { 4, 3, __KERNEL_CS, (unsigned long)overflow },
- { 5, 3, __KERNEL_CS, (unsigned long)bounds },
- { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
- { 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
- { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
- { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
- { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
- { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
- { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
- { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
- { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
- { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
- { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
- { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
- { 0, 0, 0, 0 }
-};
-
-
-
-void trap_init(void)
-{
- HYPERVISOR_set_trap_table(trap_table);
-}
-
-void trap_fini(void)
-{
- HYPERVISOR_set_trap_table(NULL);
-}
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/x86/arch_limits.h>
-#include <xen/arch-x86_32.h>
-
-.section __xen_guest
- .ascii "GUEST_OS=Mini-OS"
- .ascii ",XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
- .ascii ",ELF_PADDR_OFFSET=0x0"
- .ascii ",HYPERCALL_PAGE=0x2"
- .ascii ",PAE=yes[extended-cr3]"
- .ascii ",LOADER=generic"
- .byte 0
-.text
-
-.globl _start, shared_info, hypercall_page
-
-_start:
- cld
- lss stack_start,%esp
- andl $(~(__STACK_SIZE-1)), %esp
- push %esi
- call arch_init
-
-stack_start:
- .long stack+(2*__STACK_SIZE), __KERNEL_SS
-
- /* Unpleasant -- the PTE that maps this page is actually overwritten */
- /* to map the real shared-info page! :-) */
- .org 0x1000
-shared_info:
- .org 0x2000
-
-hypercall_page:
- .org 0x3000
-
-ES = 0x20
-ORIG_EAX = 0x24
-EIP = 0x28
-CS = 0x2C
-
-#define ENTRY(X) .globl X ; X :
-
-#define SAVE_ALL \
- cld; \
- pushl %es; \
- pushl %ds; \
- pushl %eax; \
- pushl %ebp; \
- pushl %edi; \
- pushl %esi; \
- pushl %edx; \
- pushl %ecx; \
- pushl %ebx; \
- movl $(__KERNEL_DS),%edx; \
- movl %edx,%ds; \
- movl %edx,%es;
-
-#define RESTORE_ALL \
- popl %ebx; \
- popl %ecx; \
- popl %edx; \
- popl %esi; \
- popl %edi; \
- popl %ebp; \
- popl %eax; \
- popl %ds; \
- popl %es; \
- addl $4,%esp; \
- iret;
-
-ENTRY(divide_error)
- pushl $0 # no error code
- pushl $do_divide_error
-do_exception:
- pushl %ds
- pushl %eax
- xorl %eax, %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- decl %eax # eax = -1
- pushl %ecx
- pushl %ebx
- cld
- movl %es, %ecx
- movl ES(%esp), %edi # get the function address
- movl ORIG_EAX(%esp), %edx # get the error code
- movl %eax, ORIG_EAX(%esp)
- movl %ecx, ES(%esp)
- movl $(__KERNEL_DS), %ecx
- movl %ecx, %ds
- movl %ecx, %es
- movl %esp,%eax # pt_regs pointer
- pushl %edx
- pushl %eax
- call *%edi
- jmp ret_from_exception
-
-ret_from_exception:
- movb CS(%esp),%cl
- addl $8,%esp
- RESTORE_ALL
-
-# A note on the "critical region" in our callback handler.
-# We want to avoid stacking callback handlers due to events occurring
-# during handling of the last event. To do this, we keep events disabled
-# until weve done all processing. HOWEVER, we must enable events before
-# popping the stack frame (cant be done atomically) and so it would still
-# be possible to get enough handler activations to overflow the stack.
-# Although unlikely, bugs of that kind are hard to track down, so wed
-# like to avoid the possibility.
-# So, on entry to the handler we detect whether we interrupted an
-# existing activation in its critical region -- if so, we pop the current
-# activation and restart the handler using the previous one.
-ENTRY(hypervisor_callback)
- pushl %eax
- SAVE_ALL
- movl EIP(%esp),%eax
- cmpl $scrit,%eax
- jb 11f
- cmpl $ecrit,%eax
- jb critical_region_fixup
-11: push %esp
- xorl %ebp,%ebp
- call do_hypervisor_callback
- add $4,%esp
- movl HYPERVISOR_shared_info,%esi
- xorl %eax,%eax
- movb CS(%esp),%cl
- test $2,%cl # slow return to ring 2 or 3
- jne safesti
-safesti:movb $0,1(%esi) # reenable event callbacks
-scrit: /**** START OF CRITICAL REGION ****/
- testb $0xFF,(%esi)
- jnz 14f # process more events if necessary...
- RESTORE_ALL
-14: movb $1,1(%esi)
- jmp 11b
-ecrit: /**** END OF CRITICAL REGION ****/
-# [How we do the fixup]. We want to merge the current stack frame with the
-# just-interrupted frame. How we do this depends on where in the critical
-# region the interrupted handler was executing, and so how many saved
-# registers are in each frame. We do this quickly using the lookup table
-# 'critical_fixup_table'. For each byte offset in the critical region, it
-# provides the number of bytes which have already been popped from the
-# interrupted stack frame.
-critical_region_fixup:
- addl $critical_fixup_table-scrit,%eax
- movzbl (%eax),%eax # %eax contains num bytes popped
- mov %esp,%esi
- add %eax,%esi # %esi points at end of src region
- mov %esp,%edi
- add $0x34,%edi # %edi points at end of dst region
- mov %eax,%ecx
- shr $2,%ecx # convert words to bytes
- je 16f # skip loop if nothing to copy
-15: subl $4,%esi # pre-decrementing copy loop
- subl $4,%edi
- movl (%esi),%eax
- movl %eax,(%edi)
- loop 15b
-16: movl %edi,%esp # final %edi is top of merged stack
- jmp 11b
-
-critical_fixup_table:
- .byte 0x00,0x00,0x00 # testb $0xff,(%esi)
- .byte 0x00,0x00 # jne 14f
- .byte 0x00 # pop %ebx
- .byte 0x04 # pop %ecx
- .byte 0x08 # pop %edx
- .byte 0x0c # pop %esi
- .byte 0x10 # pop %edi
- .byte 0x14 # pop %ebp
- .byte 0x18 # pop %eax
- .byte 0x1c # pop %ds
- .byte 0x20 # pop %es
- .byte 0x24,0x24,0x24 # add $4,%esp
- .byte 0x28 # iret
- .byte 0x00,0x00,0x00,0x00 # movb $1,1(%esi)
- .byte 0x00,0x00 # jmp 11b
-
-# Hypervisor uses this for application faults while it executes.
-ENTRY(failsafe_callback)
- pop %ds
- pop %es
- pop %fs
- pop %gs
- iret
-
-ENTRY(coprocessor_error)
- pushl $0
- pushl $do_coprocessor_error
- jmp do_exception
-
-ENTRY(simd_coprocessor_error)
- pushl $0
- pushl $do_simd_coprocessor_error
- jmp do_exception
-
-ENTRY(device_not_available)
- iret
-
-ENTRY(debug)
- pushl $0
- pushl $do_debug
- jmp do_exception
-
-ENTRY(int3)
- pushl $0
- pushl $do_int3
- jmp do_exception
-
-ENTRY(overflow)
- pushl $0
- pushl $do_overflow
- jmp do_exception
-
-ENTRY(bounds)
- pushl $0
- pushl $do_bounds
- jmp do_exception
-
-ENTRY(invalid_op)
- pushl $0
- pushl $do_invalid_op
- jmp do_exception
-
-
-ENTRY(coprocessor_segment_overrun)
- pushl $0
- pushl $do_coprocessor_segment_overrun
- jmp do_exception
-
-
-ENTRY(invalid_TSS)
- pushl $do_invalid_TSS
- jmp do_exception
-
-
-ENTRY(segment_not_present)
- pushl $do_segment_not_present
- jmp do_exception
-
-
-ENTRY(stack_segment)
- pushl $do_stack_segment
- jmp do_exception
-
-
-ENTRY(general_protection)
- pushl $do_general_protection
- jmp do_exception
-
-
-ENTRY(alignment_check)
- pushl $do_alignment_check
- jmp do_exception
-
-
-ENTRY(page_fault)
- pushl $do_page_fault
- jmp do_exception
-
-ENTRY(machine_check)
- pushl $0
- pushl $do_machine_check
- jmp do_exception
-
-
-ENTRY(spurious_interrupt_bug)
- pushl $0
- pushl $do_spurious_interrupt_bug
- jmp do_exception
-
-
-
-ENTRY(thread_starter)
- popl %eax
- popl %ebx
- pushl $0
- xorl %ebp,%ebp
- pushl %eax
- call *%ebx
- call exit_thread
-
-ENTRY(__arch_switch_threads)
- movl 4(%esp), %ecx /* prev */
- movl 8(%esp), %edx /* next */
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl %esp, (%ecx) /* save ESP */
- movl (%edx), %esp /* restore ESP */
- movl $1f, 4(%ecx) /* save EIP */
- pushl 4(%edx) /* restore EIP */
- ret
-1:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
+++ /dev/null
-#include <mini-os/os.h>
-#include <mini-os/x86/arch_limits.h>
-#include <xen/features.h>
-
-.section __xen_guest
- .ascii "GUEST_OS=Mini-OS"
- .ascii ",XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
- .ascii ",ELF_PADDR_OFFSET=0x0"
- .ascii ",HYPERCALL_PAGE=0x2"
- .ascii ",LOADER=generic"
- .byte 0
-.text
-
-#define ENTRY(X) .globl X ; X :
-.globl _start, shared_info, hypercall_page
-
-
-_start:
- cld
- movq stack_start(%rip),%rsp
- andq $(~(__STACK_SIZE-1)), %rsp
- movq %rsi,%rdi
- call arch_init
-
-stack_start:
- .quad stack+(2*__STACK_SIZE)
-
- /* Unpleasant -- the PTE that maps this page is actually overwritten */
- /* to map the real shared-info page! :-) */
- .org 0x1000
-shared_info:
- .org 0x2000
-
-hypercall_page:
- .org 0x3000
-
-
-#define XEN_GET_VCPU_INFO(reg) movq HYPERVISOR_shared_info,reg
-#define XEN_PUT_VCPU_INFO(reg)
-#define XEN_PUT_VCPU_INFO_fixup
-#define XEN_LOCKED_BLOCK_EVENTS(reg) movb $1,evtchn_upcall_mask(reg)
-#define XEN_LOCKED_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg)
-#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
-
-#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
- XEN_LOCKED_BLOCK_EVENTS(reg) ; \
- XEN_PUT_VCPU_INFO(reg)
-
-#define XEN_UNBLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
- XEN_LOCKED_UNBLOCK_EVENTS(reg) ; \
- XEN_PUT_VCPU_INFO(reg)
-
-
-/* Offsets into shared_info_t. */
-#define evtchn_upcall_pending /* 0 */
-#define evtchn_upcall_mask 1
-
-NMI_MASK = 0x80000000
-KERNEL_CS_MASK = 0xfc
-
-#define RAX 80
-#define RDI 112
-#define ORIG_RAX 120 /* + error_code */
-#define RIP 128
-#define CS 136
-#define RFLAGS 144
-#define RSP 152
-
-
-/* Macros */
-.macro zeroentry sym
- movq (%rsp),%rcx
- movq 8(%rsp),%r11
- addq $0x10,%rsp /* skip rcx and r11 */
- pushq $0 /* push error code/oldrax */
- pushq %rax /* push real oldrax to the rdi slot */
- leaq \sym(%rip),%rax
- jmp error_entry
-.endm
-
-.macro errorentry sym
- movq (%rsp),%rcx
- movq 8(%rsp),%r11
- addq $0x10,%rsp /* rsp points to the error code */
- pushq %rax
- leaq \sym(%rip),%rax
- jmp error_entry
-.endm
-
-.macro RESTORE_ALL
- movq (%rsp),%r11
- movq 1*8(%rsp),%r10
- movq 2*8(%rsp),%r9
- movq 3*8(%rsp),%r8
- movq 4*8(%rsp),%rax
- movq 5*8(%rsp),%rcx
- movq 6*8(%rsp),%rdx
- movq 7*8(%rsp),%rsi
- movq 8*8(%rsp),%rdi
- addq $9*8+8,%rsp
-.endm
-
-.macro RESTORE_REST
- movq (%rsp),%r15
- movq 1*8(%rsp),%r14
- movq 2*8(%rsp),%r13
- movq 3*8(%rsp),%r12
- movq 4*8(%rsp),%rbp
- movq 5*8(%rsp),%rbx
- addq $6*8,%rsp
-.endm
-
-.macro SAVE_REST
- subq $6*8,%rsp
- movq %rbx,5*8(%rsp)
- movq %rbp,4*8(%rsp)
- movq %r12,3*8(%rsp)
- movq %r13,2*8(%rsp)
- movq %r14,1*8(%rsp)
- movq %r15,(%rsp)
-.endm
-
-.macro HYPERVISOR_IRET flag
- testl $NMI_MASK,2*8(%rsp)
- jnz 2f
-
- /* Direct iret to kernel space. Correct CS and SS. */
- orb $3,1*8(%rsp)
- orb $3,4*8(%rsp)
- iretq
-
-2: /* Slow iret via hypervisor. */
- andl $~NMI_MASK, 16(%rsp)
- pushq $\flag
- jmp hypercall_page + (__HYPERVISOR_iret * 32)
-.endm
-
-
-/*
- * Exception entry point. This expects an error code/orig_rax on the stack
- * and the exception handler in %rax.
- */
-ENTRY(error_entry)
- /* rdi slot contains rax, oldrax contains error code */
- cld
- subq $14*8,%rsp
- movq %rsi,13*8(%rsp)
- movq 14*8(%rsp),%rsi /* load rax from rdi slot */
- movq %rdx,12*8(%rsp)
- movq %rcx,11*8(%rsp)
- movq %rsi,10*8(%rsp) /* store rax */
- movq %r8, 9*8(%rsp)
- movq %r9, 8*8(%rsp)
- movq %r10,7*8(%rsp)
- movq %r11,6*8(%rsp)
- movq %rbx,5*8(%rsp)
- movq %rbp,4*8(%rsp)
- movq %r12,3*8(%rsp)
- movq %r13,2*8(%rsp)
- movq %r14,1*8(%rsp)
- movq %r15,(%rsp)
-
-error_call_handler:
- movq %rdi, RDI(%rsp)
- movq %rsp,%rdi
- movq ORIG_RAX(%rsp),%rsi # get error code
- movq $-1,ORIG_RAX(%rsp)
- call *%rax
- jmp error_exit
-
-
-/*
- * Xen event (virtual interrupt) entry point.
- */
-ENTRY(hypervisor_callback)
- zeroentry hypervisor_callback2
-
-ENTRY(hypervisor_callback2)
- movq %rdi, %rsp
-
- /* check against event re-entrant */
- movq RIP(%rsp),%rax
- cmpq $scrit,%rax
- jb 11f
- cmpq $ecrit,%rax
- jb critical_region_fixup
-
-11: movq %gs:8,%rax
- incl %gs:0
- cmovzq %rax,%rsp
- pushq %rdi
- call do_hypervisor_callback
- popq %rsp
- decl %gs:0
-
-error_exit:
-retint_kernel:
- movl RFLAGS(%rsp), %eax
- shr $9, %eax # EAX[0] == IRET_RFLAGS.IF
- XEN_GET_VCPU_INFO(%rsi)
- andb evtchn_upcall_mask(%rsi),%al
- andb $1,%al # EAX[0] == IRET_RFLAGS.IF & event_mask
- jnz restore_all_enable_events # != 0 => enable event delivery
- XEN_PUT_VCPU_INFO(%rsi)
-
-retint_restore_args:
- RESTORE_REST
- RESTORE_ALL
- HYPERVISOR_IRET 0
-
-restore_all_enable_events:
- RESTORE_REST
- RESTORE_ALL
- pushq %rax # save rax for it will be clobbered later
- RSP_OFFSET=8 # record the stack frame layout changes
- XEN_GET_VCPU_INFO(%rax) # safe to use rax since it is saved
- XEN_UNBLOCK_EVENTS(%rax)
-
-scrit: /**** START OF CRITICAL REGION ****/
- XEN_TEST_PENDING(%rax)
- jz 12f
- XEN_LOCKED_BLOCK_EVENTS(%rax) # if pending, mask events and handle
- # by jumping to hypervisor_prologue
-12: popq %rax # all registers restored from this point
-
-restore_end:
- jnz hypervisor_prologue # safe to jump out of critical region
- # because events are masked if ZF = 0
- HYPERVISOR_IRET 0
-ecrit: /**** END OF CRITICAL REGION ****/
-
-# Set up the stack as Xen does before calling event callback
-hypervisor_prologue:
- pushq %r11
- pushq %rcx
- jmp hypervisor_callback
-
-# [How we do the fixup]. We want to merge the current stack frame with the
-# just-interrupted frame. How we do this depends on where in the critical
-# region the interrupted handler was executing, and so if rax has been
-# restored. We determine by comparing interrupted rip with "restore_end".
-# We always copy all registers below RIP from the current stack frame
-# to the end of the previous activation frame so that we can continue
-# as if we've never even reached 11 running in the old activation frame.
-
-critical_region_fixup:
- # Set up source and destination region pointers
- leaq RIP(%rsp),%rsi # esi points at end of src region
- # Acquire interrupted rsp which was saved-on-stack. This points to
- # the end of dst region. Note that it is not necessarily current rsp
- # plus 0xb0, because the second interrupt might align the stack frame.
- movq RSP(%rsp),%rdi # edi points at end of dst region
-
- cmpq $restore_end,%rax
- jae 13f
-
- # If interrupted rip is before restore_end
- # then rax hasn't been restored yet
- movq (%rdi),%rax
- movq %rax, RAX(%rsp) # save rax
- addq $RSP_OFFSET,%rdi
-
- # Set up the copy
-13: movq $RIP,%rcx
- shr $3,%rcx # convert bytes into count of 64-bit entities
-15: subq $8,%rsi # pre-decrementing copy loop
- subq $8,%rdi
- movq (%rsi),%rax
- movq %rax,(%rdi)
- loop 15b
-16: movq %rdi,%rsp # final rdi is top of merged stack
- andb $KERNEL_CS_MASK,CS(%rsp) # CS might have changed
- jmp 11b
-
-
-
-ENTRY(failsafe_callback)
- popq %rcx
- popq %r11
- iretq
-
-
-ENTRY(coprocessor_error)
- zeroentry do_coprocessor_error
-
-
-ENTRY(simd_coprocessor_error)
- zeroentry do_simd_coprocessor_error
-
-
-ENTRY(device_not_available)
- zeroentry do_device_not_available
-
-
-ENTRY(debug)
- zeroentry do_debug
-
-
-ENTRY(int3)
- zeroentry do_int3
-
-ENTRY(overflow)
- zeroentry do_overflow
-
-
-ENTRY(bounds)
- zeroentry do_bounds
-
-
-ENTRY(invalid_op)
- zeroentry do_invalid_op
-
-
-ENTRY(coprocessor_segment_overrun)
- zeroentry do_coprocessor_segment_overrun
-
-
-ENTRY(invalid_TSS)
- errorentry do_invalid_TSS
-
-
-ENTRY(segment_not_present)
- errorentry do_segment_not_present
-
-
-/* runs on exception stack */
-ENTRY(stack_segment)
- errorentry do_stack_segment
-
-
-ENTRY(general_protection)
- errorentry do_general_protection
-
-
-ENTRY(alignment_check)
- errorentry do_alignment_check
-
-
-ENTRY(divide_error)
- zeroentry do_divide_error
-
-
-ENTRY(spurious_interrupt_bug)
- zeroentry do_spurious_interrupt_bug
-
-
-ENTRY(page_fault)
- errorentry do_page_fault
-
-
-
-
-
-ENTRY(thread_starter)
- popq %rdi
- popq %rbx
- pushq $0
- xorq %rbp,%rbp
- call *%rbx
- call exit_thread
-
-
-ENTRY(__arch_switch_threads)
- pushq %rbp
- pushq %rbx
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
- movq %rsp, (%rdi) /* save ESP */
- movq (%rsi), %rsp /* restore ESP */
- movq $1f, 8(%rdi) /* save EIP */
- pushq 8(%rsi) /* restore EIP */
- ret
-1:
- popq %r15
- popq %r14
- popq %r13
- popq %r12
- popq %rbx
- popq %rbp
- ret
+++ /dev/null
-/* Minimal block driver for Mini-OS.
- * Copyright (c) 2007-2008 Samuel Thibault.
- * Based on netfront.c.
- */
-
-#include <stdint.h>
-#include <mini-os/os.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <errno.h>
-#include <xen/io/blkif.h>
-#include <xen/io/protocols.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/xmalloc.h>
-#include <time.h>
-#include <mini-os/blkfront.h>
-#include <mini-os/lib.h>
-#include <fcntl.h>
-
-#ifndef HAVE_LIBC
-#define strtoul simple_strtoul
-#endif
-
-/* Note: we generally don't need to disable IRQs since we hardly do anything in
- * the interrupt handler. */
-
-/* Note: we really suppose non-preemptive threads. */
-
-DECLARE_WAIT_QUEUE_HEAD(blkfront_queue);
-
-
-
-
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
-#define GRANT_INVALID_REF 0
-
-
-struct blk_buffer {
- void* page;
- grant_ref_t gref;
-};
-
-struct blkfront_dev {
- domid_t dom;
-
- struct blkif_front_ring ring;
- grant_ref_t ring_ref;
- evtchn_port_t evtchn;
- blkif_vdev_t handle;
-
- char *nodename;
- char *backend;
- struct blkfront_info info;
-
- xenbus_event_queue events;
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-};
-
-void blkfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
-#ifdef HAVE_LIBC
- struct blkfront_dev *dev = data;
- int fd = dev->fd;
-
- if (fd != -1)
- files[fd].read = 1;
-#endif
- wake_up(&blkfront_queue);
-}
-
-static void free_blkfront(struct blkfront_dev *dev)
-{
- mask_evtchn(dev->evtchn);
-
- free(dev->backend);
-
- gnttab_end_access(dev->ring_ref);
- free_page(dev->ring.sring);
-
- unbind_evtchn(dev->evtchn);
-
- free(dev->nodename);
- free(dev);
-}
-
-struct blkfront_dev *init_blkfront(char *_nodename, struct blkfront_info *info)
-{
- xenbus_transaction_t xbt;
- char* err;
- char* message=NULL;
- struct blkif_sring *s;
- int retry=0;
- char* msg = NULL;
- char* c;
- char* nodename = _nodename ? _nodename : "device/vbd/768";
-
- struct blkfront_dev *dev;
-
- char path[strlen(nodename) + strlen("/backend-id") + 1];
-
- printk("******************* BLKFRONT for %s **********\n\n\n", nodename);
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- dev->dom = xenbus_read_integer(path);
- evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn);
-
- s = (struct blkif_sring*) alloc_page();
- memset(s,0,PAGE_SIZE);
-
-
- SHARED_RING_INIT(s);
- FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE);
-
- dev->ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(s),0);
-
- dev->events = NULL;
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "ring-ref","%u",
- dev->ring_ref);
- if (err) {
- message = "writing ring-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "event-channel", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
- if (err) {
- message = "writing protocol";
- goto abort_transaction;
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateConnected);
- if (err) {
- message = "switching state";
- goto abort_transaction;
- }
-
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- if (msg) {
- printk("Error %s when reading the backend path %s\n", msg, path);
- goto error;
- }
-
- printk("backend at %s\n", dev->backend);
-
- dev->handle = strtoul(strrchr(nodename, '/')+1, NULL, 0);
-
- {
- XenbusState state;
- char path[strlen(dev->backend) + strlen("/feature-flush-cache") + 1];
- snprintf(path, sizeof(path), "%s/mode", dev->backend);
- msg = xenbus_read(XBT_NIL, path, &c);
- if (msg) {
- printk("Error %s when reading the mode\n", msg);
- goto error;
- }
- if (*c == 'w')
- dev->info.mode = O_RDWR;
- else
- dev->info.mode = O_RDONLY;
- free(c);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
- msg = NULL;
- state = xenbus_read_integer(path);
- while (msg == NULL && state < XenbusStateConnected)
- msg = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (msg != NULL || state != XenbusStateConnected) {
- printk("backend not available, state=%d\n", state);
- xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
-
- snprintf(path, sizeof(path), "%s/info", dev->backend);
- dev->info.info = xenbus_read_integer(path);
-
- snprintf(path, sizeof(path), "%s/sectors", dev->backend);
- // FIXME: read_integer returns an int, so disk size limited to 1TB for now
- dev->info.sectors = xenbus_read_integer(path);
-
- snprintf(path, sizeof(path), "%s/sector-size", dev->backend);
- dev->info.sector_size = xenbus_read_integer(path);
-
- snprintf(path, sizeof(path), "%s/feature-barrier", dev->backend);
- dev->info.barrier = xenbus_read_integer(path);
-
- snprintf(path, sizeof(path), "%s/feature-flush-cache", dev->backend);
- dev->info.flush = xenbus_read_integer(path);
-
- *info = dev->info;
- }
- unmask_evtchn(dev->evtchn);
-
- printk("%u sectors of %u bytes\n", dev->info.sectors, dev->info.sector_size);
- printk("**************************\n");
-
- return dev;
-
-error:
- free(msg);
- free(err);
- free_blkfront(dev);
- return NULL;
-}
-
-void shutdown_blkfront(struct blkfront_dev *dev)
-{
- char* err = NULL, *err2;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/event-channel") + 1];
-
- blkfront_sync(dev);
-
- printk("close blk: backend=%s node=%s\n", dev->backend, dev->nodename);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("shutdown_blkfront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("shutdown_blkfront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (state < XenbusStateClosed) {
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
- }
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
- printk("shutdown_blkfront: error changing state to %d: %s\n",
- XenbusStateInitialising, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
-
-close:
- free(err);
- err2 = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err2);
-
- snprintf(nodename, sizeof(nodename), "%s/ring-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
-
- if (!err)
- free_blkfront(dev);
-}
-
-static void blkfront_wait_slot(struct blkfront_dev *dev)
-{
- /* Wait for a slot */
- if (RING_FULL(&dev->ring)) {
- unsigned long flags;
- DEFINE_WAIT(w);
- local_irq_save(flags);
- while (1) {
- blkfront_aio_poll(dev);
- if (!RING_FULL(&dev->ring))
- break;
- /* Really no slot, go to sleep. */
- add_waiter(w, blkfront_queue);
- local_irq_restore(flags);
- schedule();
- local_irq_save(flags);
- }
- remove_waiter(w, blkfront_queue);
- local_irq_restore(flags);
- }
-}
-
-/* Issue an aio */
-void blkfront_aio(struct blkfront_aiocb *aiocbp, int write)
-{
- struct blkfront_dev *dev = aiocbp->aio_dev;
- struct blkif_request *req;
- RING_IDX i;
- int notify;
- int n, j;
- uintptr_t start, end;
-
- // Can't io at non-sector-aligned location
- ASSERT(!(aiocbp->aio_offset & (dev->info.sector_size-1)));
- // Can't io non-sector-sized amounts
- ASSERT(!(aiocbp->aio_nbytes & (dev->info.sector_size-1)));
- // Can't io non-sector-aligned buffer
- ASSERT(!((uintptr_t) aiocbp->aio_buf & (dev->info.sector_size-1)));
-
- start = (uintptr_t)aiocbp->aio_buf & PAGE_MASK;
- end = ((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes + PAGE_SIZE - 1) & PAGE_MASK;
- aiocbp->n = n = (end - start) / PAGE_SIZE;
-
- /* qemu's IDE max multsect is 16 (8KB) and SCSI max DMA was set to 32KB,
- * so max 44KB can't happen */
- ASSERT(n <= BLKIF_MAX_SEGMENTS_PER_REQUEST);
-
- blkfront_wait_slot(dev);
- i = dev->ring.req_prod_pvt;
- req = RING_GET_REQUEST(&dev->ring, i);
-
- req->operation = write ? BLKIF_OP_WRITE : BLKIF_OP_READ;
- req->nr_segments = n;
- req->handle = dev->handle;
- req->id = (uintptr_t) aiocbp;
- req->sector_number = aiocbp->aio_offset / 512;
-
- for (j = 0; j < n; j++) {
- req->seg[j].first_sect = 0;
- req->seg[j].last_sect = PAGE_SIZE / 512 - 1;
- }
- req->seg[0].first_sect = ((uintptr_t)aiocbp->aio_buf & ~PAGE_MASK) / 512;
- req->seg[n-1].last_sect = (((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes - 1) & ~PAGE_MASK) / 512;
- for (j = 0; j < n; j++) {
- uintptr_t data = start + j * PAGE_SIZE;
- if (!write) {
- /* Trigger CoW if needed */
- *(char*)(data + (req->seg[j].first_sect << 9)) = 0;
- barrier();
- }
- aiocbp->gref[j] = req->seg[j].gref =
- gnttab_grant_access(dev->dom, virtual_to_mfn(data), write);
- }
-
- dev->ring.req_prod_pvt = i + 1;
-
- wmb();
- RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify);
-
- if(notify) notify_remote_via_evtchn(dev->evtchn);
-}
-
-static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret)
-{
- aiocbp->data = (void*) 1;
- aiocbp->aio_cb = NULL;
-}
-
-void blkfront_io(struct blkfront_aiocb *aiocbp, int write)
-{
- unsigned long flags;
- DEFINE_WAIT(w);
-
- ASSERT(!aiocbp->aio_cb);
- aiocbp->aio_cb = blkfront_aio_cb;
- blkfront_aio(aiocbp, write);
- aiocbp->data = NULL;
-
- local_irq_save(flags);
- while (1) {
- blkfront_aio_poll(aiocbp->aio_dev);
- if (aiocbp->data)
- break;
-
- add_waiter(w, blkfront_queue);
- local_irq_restore(flags);
- schedule();
- local_irq_save(flags);
- }
- remove_waiter(w, blkfront_queue);
- local_irq_restore(flags);
-}
-
-static void blkfront_push_operation(struct blkfront_dev *dev, uint8_t op, uint64_t id)
-{
- int i;
- struct blkif_request *req;
- int notify;
-
- blkfront_wait_slot(dev);
- i = dev->ring.req_prod_pvt;
- req = RING_GET_REQUEST(&dev->ring, i);
- req->operation = op;
- req->nr_segments = 0;
- req->handle = dev->handle;
- req->id = id;
- /* Not needed anyway, but the backend will check it */
- req->sector_number = 0;
- dev->ring.req_prod_pvt = i + 1;
- wmb();
- RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify);
- if (notify) notify_remote_via_evtchn(dev->evtchn);
-}
-
-void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op)
-{
- struct blkfront_dev *dev = aiocbp->aio_dev;
- blkfront_push_operation(dev, op, (uintptr_t) aiocbp);
-}
-
-void blkfront_sync(struct blkfront_dev *dev)
-{
- unsigned long flags;
- DEFINE_WAIT(w);
-
- if (dev->info.mode == O_RDWR) {
- if (dev->info.barrier == 1)
- blkfront_push_operation(dev, BLKIF_OP_WRITE_BARRIER, 0);
-
- if (dev->info.flush == 1)
- blkfront_push_operation(dev, BLKIF_OP_FLUSH_DISKCACHE, 0);
- }
-
- /* Note: This won't finish if another thread enqueues requests. */
- local_irq_save(flags);
- while (1) {
- blkfront_aio_poll(dev);
- if (RING_FREE_REQUESTS(&dev->ring) == RING_SIZE(&dev->ring))
- break;
-
- add_waiter(w, blkfront_queue);
- local_irq_restore(flags);
- schedule();
- local_irq_save(flags);
- }
- remove_waiter(w, blkfront_queue);
- local_irq_restore(flags);
-}
-
-int blkfront_aio_poll(struct blkfront_dev *dev)
-{
- RING_IDX rp, cons;
- struct blkif_response *rsp;
- int more;
- int nr_consumed;
-
-moretodo:
-#ifdef HAVE_LIBC
- if (dev->fd != -1) {
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
- }
-#endif
-
- rp = dev->ring.sring->rsp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
- cons = dev->ring.rsp_cons;
-
- nr_consumed = 0;
- while ((cons != rp))
- {
- struct blkfront_aiocb *aiocbp;
- int status;
-
- rsp = RING_GET_RESPONSE(&dev->ring, cons);
- nr_consumed++;
-
- aiocbp = (void*) (uintptr_t) rsp->id;
- status = rsp->status;
-
- switch (rsp->operation) {
- case BLKIF_OP_READ:
- case BLKIF_OP_WRITE:
- {
- int j;
-
- if (status != BLKIF_RSP_OKAY)
- printk("%s error %d on %s at offset %llu, num bytes %llu\n",
- rsp->operation == BLKIF_OP_READ?"read":"write",
- status, aiocbp->aio_dev->nodename,
- (unsigned long long) aiocbp->aio_offset,
- (unsigned long long) aiocbp->aio_nbytes);
-
- for (j = 0; j < aiocbp->n; j++)
- gnttab_end_access(aiocbp->gref[j]);
-
- break;
- }
-
- case BLKIF_OP_WRITE_BARRIER:
- if (status != BLKIF_RSP_OKAY)
- printk("write barrier error %d\n", status);
- break;
- case BLKIF_OP_FLUSH_DISKCACHE:
- if (status != BLKIF_RSP_OKAY)
- printk("flush error %d\n", status);
- break;
-
- default:
- printk("unrecognized block operation %d response (status %d)\n", rsp->operation, status);
- break;
- }
-
- dev->ring.rsp_cons = ++cons;
- /* Nota: callback frees aiocbp itself */
- if (aiocbp && aiocbp->aio_cb)
- aiocbp->aio_cb(aiocbp, status ? -EIO : 0);
- if (dev->ring.rsp_cons != cons)
- /* We reentered, we must not continue here */
- break;
- }
-
- RING_FINAL_CHECK_FOR_RESPONSES(&dev->ring, more);
- if (more) goto moretodo;
-
- return nr_consumed;
-}
-
-#ifdef HAVE_LIBC
-int blkfront_open(struct blkfront_dev *dev)
-{
- /* Silently prevent multiple opens */
- if(dev->fd != -1) {
- return dev->fd;
- }
- dev->fd = alloc_fd(FTYPE_BLK);
- printk("blk_open(%s) -> %d\n", dev->nodename, dev->fd);
- files[dev->fd].blk.dev = dev;
- files[dev->fd].blk.offset = 0;
- return dev->fd;
-}
-
-int blkfront_posix_rwop(int fd, uint8_t* buf, size_t count, int write)
-{
- struct blkfront_dev* dev = files[fd].blk.dev;
- off_t offset = files[fd].blk.offset;
- struct blkfront_aiocb aiocb;
- unsigned long long disksize = dev->info.sectors * dev->info.sector_size;
- unsigned int blocksize = dev->info.sector_size;
-
- int blknum;
- int blkoff;
- size_t bytes;
- int rc = 0;
- int alignedbuf = 0;
- uint8_t* copybuf = NULL;
-
- /* RW 0 bytes is just a NOP */
- if(count == 0) {
- return 0;
- }
- /* Check for NULL buffer */
- if( buf == NULL ) {
- errno = EFAULT;
- return -1;
- }
-
- /* Write mode checks */
- if(write) {
- /*Make sure we have write permission */
- if(dev->info.info & VDISK_READONLY
- || (dev->info.mode != O_RDWR && dev->info.mode != O_WRONLY)) {
- errno = EACCES;
- return -1;
- }
- /*Make sure disk is big enough for this write */
- if(offset + count > disksize) {
- errno = ENOSPC;
- return -1;
- }
- }
- /* Read mode checks */
- else
- {
- /* Reading past the disk? Just return 0 */
- if(offset >= disksize) {
- return 0;
- }
-
- /*If the requested read is bigger than the disk, just
- * read as much as we can until the end */
- if(offset + count > disksize) {
- count = disksize - offset;
- }
- }
- /* Determine which block to start at and at which offset inside of it */
- blknum = offset / blocksize;
- blkoff = offset % blocksize;
-
- /* Optimization: We need to check if buf is aligned to the sector size.
- * This is somewhat tricky code. We have to add the blocksize - block offset
- * because the first block may be a partial block and then for every subsequent
- * block rw the buffer will be offset.*/
- if(!((uintptr_t) (buf +(blocksize - blkoff)) & (dev->info.sector_size-1))) {
- alignedbuf = 1;
- }
-
- /* Setup aiocb block object */
- aiocb.aio_dev = dev;
- aiocb.aio_offset = blknum * blocksize;
- aiocb.aio_cb = NULL;
- aiocb.data = NULL;
-
- /* If our buffer is unaligned or its aligned but we will need to rw a partial block
- * then a copy will have to be done */
- if(!alignedbuf || blkoff != 0 || count % blocksize != 0) {
- copybuf = _xmalloc(blocksize, dev->info.sector_size);
- }
-
- rc = count;
- while(count > 0) {
- /* determine how many bytes to read/write from/to the current block buffer */
- if(!alignedbuf || blkoff != 0 || count < blocksize) {
- /* This is the case for unaligned R/W or partial block */
- bytes = count < blocksize - blkoff ? count : blocksize - blkoff;
- aiocb.aio_nbytes = blocksize;
- } else {
- /* We can optimize further if buffer is page aligned */
- int not_page_aligned = 0;
- if(((uintptr_t)buf) & (PAGE_SIZE -1)) {
- not_page_aligned = 1;
- }
-
- /* For an aligned R/W we can read up to the maximum transfer size */
- bytes = count > (BLKIF_MAX_SEGMENTS_PER_REQUEST-not_page_aligned)*PAGE_SIZE
- ? (BLKIF_MAX_SEGMENTS_PER_REQUEST-not_page_aligned)*PAGE_SIZE
- : count & ~(blocksize -1);
- aiocb.aio_nbytes = bytes;
- }
-
- /* read operation */
- if(!write) {
- if (alignedbuf && bytes >= blocksize) {
- /* If aligned and were reading a whole block, just read right into buf */
- aiocb.aio_buf = buf;
- blkfront_read(&aiocb);
- } else {
- /* If not then we have to do a copy */
- aiocb.aio_buf = copybuf;
- blkfront_read(&aiocb);
- memcpy(buf, ©buf[blkoff], bytes);
- }
- }
- /* Write operation */
- else {
- if(alignedbuf && bytes >= blocksize) {
- /* If aligned and were writing a whole block, just write directly from buf */
- aiocb.aio_buf = buf;
- blkfront_write(&aiocb);
- } else {
- /* If not then we have to do a copy. */
- aiocb.aio_buf = copybuf;
- /* If we're writing a partial block, we need to read the current contents first
- * so we don't overwrite the extra bits with garbage */
- if(blkoff != 0 || bytes < blocksize) {
- blkfront_read(&aiocb);
- }
- memcpy(©buf[blkoff], buf, bytes);
- blkfront_write(&aiocb);
- }
- }
- /* Will start at beginning of all remaining blocks */
- blkoff = 0;
-
- /* Increment counters and continue */
- count -= bytes;
- buf += bytes;
- if(bytes < blocksize) {
- //At minimum we read one block
- aiocb.aio_offset += blocksize;
- } else {
- //If we read more than a block, was a multiple of blocksize
- aiocb.aio_offset += bytes;
- }
- }
-
- free(copybuf);
- files[fd].blk.offset += rc;
- return rc;
-
-}
-
-int blkfront_posix_fstat(int fd, struct stat* buf)
-{
- struct blkfront_dev* dev = files[fd].blk.dev;
-
- buf->st_mode = dev->info.mode;
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_size = dev->info.sectors * dev->info.sector_size;
- buf->st_atime = buf->st_mtime = buf->st_ctime = time(NULL);
-
- return 0;
-}
-#endif
+++ /dev/null
-include $(MINI-OS_ROOT)/config/StdGNU.mk
-include $(MINI-OS_ROOT)/Config.mk
-CFLAGS += $(DEF_CFLAGS) $(ARCH_CFLAGS)
-CPPFLAGS += $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS) $(extra_incl)
-ASFLAGS += $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
-LDFLAGS += $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
-
-# Override settings for this OS
-PTHREAD_LIBS =
-nosharedlibs=y
+++ /dev/null
-AS = $(CROSS_COMPILE)as
-LD = $(CROSS_COMPILE)ld
-ifeq ($(clang),y)
-CC = $(CROSS_COMPILE)clang
-LD_LTO = $(CROSS_COMPILE)llvm-ld
-else
-CC = $(CROSS_COMPILE)gcc
-LD_LTO = $(CROSS_COMPILE)ld
-endif
-CPP = $(CC) -E
-AR = $(CROSS_COMPILE)ar
-RANLIB = $(CROSS_COMPILE)ranlib
-NM = $(CROSS_COMPILE)nm
-STRIP = $(CROSS_COMPILE)strip
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
-SIZEUTIL = $(CROSS_COMPILE)size
-
-# Allow git to be wrappered in the environment
-GIT ?= git
-
-INSTALL = install
-INSTALL_DIR = $(INSTALL) -d -m0755 -p
-INSTALL_DATA = $(INSTALL) -m0644 -p
-INSTALL_PROG = $(INSTALL) -m0755 -p
-
-BOOT_DIR ?= /boot
-
-SOCKET_LIBS =
-UTIL_LIBS = -lutil
-DLOPEN_LIBS = -ldl
-
-SONAME_LDFLAG = -soname
-SHLIB_LDFLAGS = -shared
-
-ifneq ($(debug),y)
-CFLAGS += -O2 -fomit-frame-pointer
-else
-# Less than -O1 produces bad code and large stack frames
-CFLAGS += -O1 -fno-omit-frame-pointer
-CFLAGS-$(gcc) += -fno-optimize-sibling-calls
-endif
-
-ifeq ($(lto),y)
-CFLAGS += -flto
-LDFLAGS-$(clang) += -plugin LLVMgold.so
-endif
+++ /dev/null
-CONFIG_ARM := y
-CONFIG_ARM_32 := y
-CONFIG_ARM_$(XEN_OS) := y
-
-CONFIG_XEN_INSTALL_SUFFIX :=
-
-# -march= -mcpu=
-
-# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
-CFLAGS += -marm
-
-HAS_PL011 := y
-HAS_EXYNOS4210 := y
-HAS_OMAP := y
-HAS_NS16550 := y
-
-# Use only if calling $(LD) directly.
-LDFLAGS_DIRECT += -EL
-
-CONFIG_LOAD_ADDRESS ?= 0x80000000
-
-IOEMU_CPU_ARCH ?= arm
+++ /dev/null
-CONFIG_ARM := y
-CONFIG_ARM_64 := y
-CONFIG_ARM_$(XEN_OS) := y
-
-CONFIG_XEN_INSTALL_SUFFIX :=
-
-CFLAGS += #-marm -march= -mcpu= etc
-
-HAS_PL011 := y
-HAS_NS16550 := y
-
-# Use only if calling $(LD) directly.
-LDFLAGS_DIRECT += -EL
-
-CONFIG_LOAD_ADDRESS ?= 0x80000000
-
-IOEMU_CPU_ARCH ?= aarch64
-
-EFI_DIR ?= /usr/lib64/efi
+++ /dev/null
-CONFIG_X86 := y
-CONFIG_X86_32 := y
-CONFIG_X86_$(XEN_OS) := y
-
-CONFIG_HVM := y
-CONFIG_MIGRATE := y
-CONFIG_XCUTILS := y
-
-HAS_MEM_ACCESS := y
-HAS_MEM_PAGING := y
-HAS_MEM_SHARING := y
-
-CFLAGS += -m32 -march=i686
-
-# Use only if calling $(LD) directly.
-LDFLAGS_DIRECT_OpenBSD = _obsd
-LDFLAGS_DIRECT_FreeBSD = _fbsd
-LDFLAGS_DIRECT += -melf_i386$(LDFLAGS_DIRECT_$(XEN_OS))
-
-IOEMU_CPU_ARCH ?= i386
+++ /dev/null
-CONFIG_X86 := y
-CONFIG_X86_64 := y
-CONFIG_X86_$(XEN_OS) := y
-
-CONFIG_COMPAT := y
-CONFIG_HVM := y
-CONFIG_MIGRATE := y
-CONFIG_XCUTILS := y
-
-HAS_MEM_ACCESS := y
-HAS_MEM_PAGING := y
-HAS_MEM_SHARING := y
-
-CONFIG_XEN_INSTALL_SUFFIX := .gz
-
-CFLAGS += -m64
-
-SunOS_LIBDIR = $(SunOS_LIBDIR_x86_64)
-
-EFI_DIR ?= /usr/lib64/efi
-
-# Use only if calling $(LD) directly.
-ifeq ($(XEN_OS),OpenBSD)
-LDFLAGS_DIRECT += -melf_x86_64_obsd
-else
-ifeq ($(XEN_OS),FreeBSD)
-LDFLAGS_DIRECT += -melf_x86_64_fbsd
-else
-LDFLAGS_DIRECT += -melf_x86_64
-endif
-endif
-
-IOEMU_CPU_ARCH ?= x86_64
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2006 - Grzegorz Milos - Cambridge University
- ****************************************************************************
- *
- * File: console.h
- * Author: Grzegorz Milos
- * Changes:
- *
- * Date: Mar 2006
- *
- * Environment: Xen Minimal OS
- * Description: Console interface.
- *
- * Handles console I/O. Defines printk.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/types.h>
-#include <mini-os/wait.h>
-#include <mini-os/mm.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/xenbus.h>
-#include <xen/io/console.h>
-
-
-/* Copies all print output to the Xen emergency console apart
- of standard dom0 handled console */
-#define USE_XEN_CONSOLE
-
-
-/* If console not initialised the printk will be sent to xen serial line
- NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
-static int console_initialised = 0;
-
-__attribute__((weak)) void console_input(char * buf, unsigned len)
-{
- if(len > 0)
- {
- /* Just repeat what's written */
- buf[len] = '\0';
- printk("%s", buf);
-
- if(buf[len-1] == '\r')
- printk("\nNo console input handler.\n");
- }
-}
-
-#ifndef HAVE_LIBC
-void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
-{
- console_input(buf, len);
-}
-
-void xencons_tx(void)
-{
- /* Do nothing, handled by _rx */
-}
-#endif
-
-
-void console_print(struct consfront_dev *dev, char *data, int length)
-{
- char *curr_char, saved_char;
- char copied_str[length+1];
- char *copied_ptr;
- int part_len;
- int (*ring_send_fn)(struct consfront_dev *dev, const char *data, unsigned length);
-
- if(!console_initialised)
- ring_send_fn = xencons_ring_send_no_notify;
- else
- ring_send_fn = xencons_ring_send;
-
- copied_ptr = copied_str;
- memcpy(copied_ptr, data, length);
- for(curr_char = copied_ptr; curr_char < copied_ptr+length-1; curr_char++)
- {
- if(*curr_char == '\n')
- {
- *curr_char = '\r';
- saved_char = *(curr_char+1);
- *(curr_char+1) = '\n';
- part_len = curr_char - copied_ptr + 2;
- ring_send_fn(dev, copied_ptr, part_len);
- *(curr_char+1) = saved_char;
- copied_ptr = curr_char+1;
- length -= part_len - 1;
- }
- }
-
- if (copied_ptr[length-1] == '\n') {
- copied_ptr[length-1] = '\r';
- copied_ptr[length] = '\n';
- length++;
- }
-
- ring_send_fn(dev, copied_ptr, length);
-}
-
-void print(int direct, const char *fmt, va_list args)
-{
- static char buf[1024];
-
- (void)vsnprintf(buf, sizeof(buf), fmt, args);
-
- if(direct)
- {
- (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
- return;
- } else {
-#ifndef USE_XEN_CONSOLE
- if(!console_initialised)
-#endif
- (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
-
- console_print(NULL, buf, strlen(buf));
- }
-}
-
-void printk(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- print(0, fmt, args);
- va_end(args);
-}
-
-void xprintk(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- print(1, fmt, args);
- va_end(args);
-}
-void init_console(void)
-{
- printk("Initialising console ... ");
- xencons_ring_init();
- console_initialised = 1;
- /* This is also required to notify the daemon */
- printk("done.\n");
-}
+++ /dev/null
-
-void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data);
+++ /dev/null
-#include <mini-os/types.h>
-#include <mini-os/wait.h>
-#include <mini-os/mm.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/xenbus.h>
-#include <xen/io/console.h>
-#include <xen/io/protocols.h>
-#include <xen/io/ring.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/gnttab.h>
-#include "console.h"
-
-void free_consfront(struct consfront_dev *dev)
-{
- char* err = NULL;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/state") + 1];
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("free_consfront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("free_consfront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close;
- }
-
-close:
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err);
-
- mask_evtchn(dev->evtchn);
- unbind_evtchn(dev->evtchn);
- free(dev->backend);
- free(dev->nodename);
-
- gnttab_end_access(dev->ring_ref);
-
- free_page(dev->ring);
- free(dev);
-}
-
-struct consfront_dev *init_consfront(char *_nodename)
-{
- xenbus_transaction_t xbt;
- char* err = NULL;
- char* message=NULL;
- int retry=0;
- char* msg = NULL;
- char nodename[256];
- char path[256];
- static int consfrontends = 3;
- struct consfront_dev *dev;
- int res;
-
- if (!_nodename)
- snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends);
- else {
- strncpy(nodename, _nodename, sizeof(nodename) - 1);
- nodename[sizeof(nodename) - 1] = 0;
- }
-
- printk("******************* CONSFRONT for %s **********\n\n\n", nodename);
-
- consfrontends++;
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- if ((res = xenbus_read_integer(path)) < 0)
- goto error;
- else
- dev->dom = res;
- evtchn_alloc_unbound(dev->dom, console_handle_input, dev, &dev->evtchn);
-
- dev->ring = (struct xencons_interface *) alloc_page();
- memset(dev->ring, 0, PAGE_SIZE);
- dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0);
-
- dev->events = NULL;
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "ring-ref","%u",
- dev->ring_ref);
- if (err) {
- message = "writing ring-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "port", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
- if (err) {
- message = "writing protocol";
- goto abort_transaction;
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateConnected);
- if (err) {
- message = "switching state";
- goto abort_transaction;
- }
-
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- if (msg) {
- printk("Error %s when reading the backend path %s\n", msg, path);
- goto error;
- }
-
- printk("backend at %s\n", dev->backend);
-
- {
- XenbusState state;
- char path[strlen(dev->backend) + strlen("/state") + 1];
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
- msg = NULL;
- state = xenbus_read_integer(path);
- while (msg == NULL && state < XenbusStateConnected)
- msg = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (msg != NULL || state != XenbusStateConnected) {
- printk("backend not available, state=%d\n", state);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
- }
- unmask_evtchn(dev->evtchn);
-
- printk("**************************\n");
-
- return dev;
-
-error:
- free(msg);
- free(err);
- free_consfront(dev);
- return NULL;
-}
-
-void fini_console(struct consfront_dev *dev)
-{
- if (dev) free_consfront(dev);
-}
-
+++ /dev/null
-#include <mini-os/types.h>
-#include <mini-os/wait.h>
-#include <mini-os/mm.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/xenbus.h>
-#include <xen/io/console.h>
-#include <xen/io/protocols.h>
-#include <xen/io/ring.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/gnttab.h>
-#include "console.h"
-
-DECLARE_WAIT_QUEUE_HEAD(console_queue);
-
-static inline void notify_daemon(struct consfront_dev *dev)
-{
- /* Use evtchn: this is called early, before irq is set up. */
- if (!dev)
- notify_remote_via_evtchn(start_info.console.domU.evtchn);
- else
- notify_remote_via_evtchn(dev->evtchn);
-}
-
-static inline struct xencons_interface *xencons_interface(void)
-{
- if (start_info.console.domU.evtchn)
- return mfn_to_virt(start_info.console.domU.mfn);
- else
- return NULL;
-}
-
-int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len)
-{
- int sent = 0;
- struct xencons_interface *intf;
- XENCONS_RING_IDX cons, prod;
-
- if (!dev)
- intf = xencons_interface();
- else
- intf = dev->ring;
- if (!intf)
- return sent;
-
- cons = intf->out_cons;
- prod = intf->out_prod;
- mb();
- BUG_ON((prod - cons) > sizeof(intf->out));
-
- while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
- intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
-
- wmb();
- intf->out_prod = prod;
-
- return sent;
-}
-
-int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len)
-{
- int sent;
-
- sent = xencons_ring_send_no_notify(dev, data, len);
- notify_daemon(dev);
-
- return sent;
-}
-
-
-
-void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
- struct consfront_dev *dev = (struct consfront_dev *) data;
-#ifdef HAVE_LIBC
- int fd = dev ? dev->fd : -1;
-
- if (fd != -1)
- files[fd].read = 1;
-
- wake_up(&console_queue);
-#else
- struct xencons_interface *intf = xencons_interface();
- XENCONS_RING_IDX cons, prod;
-
- cons = intf->in_cons;
- prod = intf->in_prod;
- mb();
- BUG_ON((prod - cons) > sizeof(intf->in));
-
- while (cons != prod) {
- xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
- cons++;
- }
-
- mb();
- intf->in_cons = cons;
-
- notify_daemon(dev);
-
- xencons_tx();
-#endif
-}
-
-#ifdef HAVE_LIBC
-int xencons_ring_avail(struct consfront_dev *dev)
-{
- struct xencons_interface *intf;
- XENCONS_RING_IDX cons, prod;
-
- if (!dev)
- intf = xencons_interface();
- else
- intf = dev->ring;
-
- cons = intf->in_cons;
- prod = intf->in_prod;
- mb();
- BUG_ON((prod - cons) > sizeof(intf->in));
-
- return prod - cons;
-}
-
-int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len)
-{
- struct xencons_interface *intf;
- XENCONS_RING_IDX cons, prod;
- unsigned filled = 0;
-
- if (!dev)
- intf = xencons_interface();
- else
- intf = dev->ring;
-
- cons = intf->in_cons;
- prod = intf->in_prod;
- mb();
- BUG_ON((prod - cons) > sizeof(intf->in));
-
- while (filled < len && cons + filled != prod) {
- data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
- filled++;
- }
-
- mb();
- intf->in_cons = cons + filled;
-
- notify_daemon(dev);
-
- return filled;
-}
-#endif
-
-struct consfront_dev *xencons_ring_init(void)
-{
- int err;
- struct consfront_dev *dev;
-
- if (!start_info.console.domU.evtchn)
- return 0;
-
- dev = malloc(sizeof(struct consfront_dev));
- memset(dev, 0, sizeof(struct consfront_dev));
- dev->nodename = "device/console";
- dev->dom = 0;
- dev->backend = 0;
- dev->ring_ref = 0;
-
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
- dev->evtchn = start_info.console.domU.evtchn;
- dev->ring = (struct xencons_interface *) mfn_to_virt(start_info.console.domU.mfn);
-
- err = bind_evtchn(dev->evtchn, console_handle_input, dev);
- if (err <= 0) {
- printk("XEN console request chn bind failed %i\n", err);
- free(dev);
- return NULL;
- }
- unmask_evtchn(dev->evtchn);
-
- /* In case we have in-flight data after save/restore... */
- notify_daemon(dev);
-
- return dev;
-}
-
-void xencons_resume(void)
-{
- (void)xencons_ring_init();
-}
-
+++ /dev/null
-/*
- * daytime.c: a simple network service based on lwIP and mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#include <os.h>
-#include <xmalloc.h>
-#include <console.h>
-#include <netfront.h>
-#include <lwip/api.h>
-
-static char message[29];
-
-void run_server(void *p)
-{
- struct ip_addr listenaddr = { 0 };
- struct netconn *listener;
- struct netconn *session;
- struct timeval tv;
- err_t rc;
-
- start_networking();
-
- if (0) {
- struct ip_addr ipaddr = { htonl(0x0a000001) };
- struct ip_addr netmask = { htonl(0xff000000) };
- struct ip_addr gw = { 0 };
- networking_set_addr(&ipaddr, &netmask, &gw);
- }
-
- tprintk("Opening connection\n");
-
- listener = netconn_new(NETCONN_TCP);
- tprintk("Connection at %p\n", listener);
-
- rc = netconn_bind(listener, &listenaddr, 13);
- if (rc != ERR_OK) {
- tprintk("Failed to bind connection: %i\n", rc);
- return;
- }
-
- rc = netconn_listen(listener);
- if (rc != ERR_OK) {
- tprintk("Failed to listen on connection: %i\n", rc);
- return;
- }
-
- while (1) {
- session = netconn_accept(listener);
- if (session == NULL)
- continue;
-
- gettimeofday(&tv, NULL);
- sprintf(message, "%20lu.%6.6lu\n", tv.tv_sec, tv.tv_usec);
- (void) netconn_write(session, message, strlen(message), NETCONN_COPY);
- (void) netconn_disconnect(session);
- (void) netconn_delete(session);
- }
-}
-
-
-int app_main(start_info_t *si)
-{
- create_thread("server", run_server, NULL);
- return 0;
-}
+++ /dev/null
-# -*- mode: python; -*-
-#============================================================================
-# Python configuration setup for 'xm create'.
-# This script sets the parameters used when a domain is created using 'xm create'.
-# You use a separate script for each domain you want to create, or
-# you can set the parameters for the domain on the xm command line.
-#============================================================================
-
-#----------------------------------------------------------------------------
-# Kernel image file.
-kernel = "mini-os.gz"
-
-# Initial memory allocation (in megabytes) for the new domain.
-memory = 32
-
-# A name for your domain. All domains must have different names.
-name = "Mini-OS"
-
-on_crash = 'destroy'
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: events.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: Jul 2003, changes Jun 2005
- *
- * Environment: Xen Minimal OS
- * Description: Deals with events recieved on event channels
- *
- ****************************************************************************
- */
-
-#include <mini-os/os.h>
-#include <mini-os/mm.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-#include <mini-os/lib.h>
-#include <xen/xsm/flask_op.h>
-
-#define NR_EVS 1024
-
-/* this represents a event handler. Chaining or sharing is not allowed */
-typedef struct _ev_action_t {
- evtchn_handler_t handler;
- void *data;
- uint32_t count;
-} ev_action_t;
-
-static ev_action_t ev_actions[NR_EVS];
-void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
-
-static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
-
-void unbind_all_ports(void)
-{
- int i;
- int cpu = 0;
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
-
- for ( i = 0; i < NR_EVS; i++ )
- {
- if ( i == start_info.console.domU.evtchn ||
- i == start_info.store_evtchn)
- continue;
-
- if ( test_and_clear_bit(i, bound_ports) )
- {
- printk("port %d still bound!\n", i);
- unbind_evtchn(i);
- }
- }
- vcpu_info->evtchn_upcall_pending = 0;
- vcpu_info->evtchn_pending_sel = 0;
-}
-
-/*
- * Demux events to different handlers.
- */
-int do_event(evtchn_port_t port, struct pt_regs *regs)
-{
- ev_action_t *action;
-
- clear_evtchn(port);
-
- if ( port >= NR_EVS )
- {
- printk("WARN: do_event(): Port number too large: %d\n", port);
- return 1;
- }
-
- action = &ev_actions[port];
- action->count++;
-
- /* call the handler */
- action->handler(port, regs, action->data);
-
- return 1;
-
-}
-
-evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
- void *data)
-{
- if ( ev_actions[port].handler != default_handler )
- printk("WARN: Handler for port %d already registered, replacing\n",
- port);
-
- ev_actions[port].data = data;
- wmb();
- ev_actions[port].handler = handler;
- set_bit(port, bound_ports);
-
- return port;
-}
-
-void unbind_evtchn(evtchn_port_t port )
-{
- struct evtchn_close close;
- int rc;
-
- if ( ev_actions[port].handler == default_handler )
- printk("WARN: No handler for port %d when unbinding\n", port);
- mask_evtchn(port);
- clear_evtchn(port);
-
- ev_actions[port].handler = default_handler;
- wmb();
- ev_actions[port].data = NULL;
- clear_bit(port, bound_ports);
-
- close.port = port;
- rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
- if ( rc )
- printk("WARN: close_port %d failed rc=%d. ignored\n", port, rc);
-}
-
-evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
-{
- evtchn_bind_virq_t op;
- int rc;
-
- /* Try to bind the virq to a port */
- op.virq = virq;
- op.vcpu = smp_processor_id();
-
- rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op);
- if (rc != 0)
- {
- printk("Failed to bind virtual IRQ %d with rc=%d\n", virq, rc);
- return -1;
- }
- bind_evtchn(op.port, handler, data);
- return op.port;
-}
-
-evtchn_port_t bind_pirq(uint32_t pirq, int will_share,
- evtchn_handler_t handler, void *data)
-{
- evtchn_bind_pirq_t op;
- int rc;
-
- /* Try to bind the pirq to a port */
- op.pirq = pirq;
- op.flags = will_share ? BIND_PIRQ__WILL_SHARE : 0;
-
- if ( (rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &op)) != 0 )
- {
- printk("Failed to bind physical IRQ %d with rc=%d\n", pirq, rc);
- return -1;
- }
- bind_evtchn(op.port, handler, data);
- return op.port;
-}
-
-/*
- * Initially all events are without a handler and disabled
- */
-void init_events(void)
-{
- int i;
-
- /* initialize event handler */
- for ( i = 0; i < NR_EVS; i++ )
- {
- ev_actions[i].handler = default_handler;
- mask_evtchn(i);
- }
-
- arch_init_events();
-}
-
-void fini_events(void)
-{
- /* Dealloc all events */
- arch_unbind_ports();
- unbind_all_ports();
- arch_fini_events();
-}
-
-void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
-{
- printk("[Port %d] - event received\n", port);
-}
-
-/* Create a port available to the pal for exchanging notifications.
- Returns the result of the hypervisor call. */
-
-/* Unfortunate confusion of terminology: the port is unbound as far
- as Xen is concerned, but we automatically bind a handler to it
- from inside mini-os. */
-
-int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
- void *data, evtchn_port_t *port)
-{
- int rc;
-
- evtchn_alloc_unbound_t op;
- op.dom = DOMID_SELF;
- op.remote_dom = pal;
- rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
- if ( rc )
- {
- printk("ERROR: alloc_unbound failed with rc=%d", rc);
- return rc;
- }
- *port = bind_evtchn(op.port, handler, data);
- return rc;
-}
-
-/* Connect to a port so as to allow the exchange of notifications with
- the pal. Returns the result of the hypervisor call. */
-
-int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
- evtchn_handler_t handler, void *data,
- evtchn_port_t *local_port)
-{
- int rc;
- evtchn_port_t port;
- evtchn_bind_interdomain_t op;
- op.remote_dom = pal;
- op.remote_port = remote_port;
- rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
- if ( rc )
- {
- printk("ERROR: bind_interdomain failed with rc=%d", rc);
- return rc;
- }
- port = op.local_port;
- *local_port = bind_evtchn(port, handler, data);
- return rc;
-}
-
-int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
-{
- int rc;
- uint32_t sid;
- struct xen_flask_op op;
- op.cmd = FLASK_GET_PEER_SID;
- op.interface_version = XEN_FLASK_INTERFACE_VERSION;
- op.u.peersid.evtchn = local_port;
- rc = HYPERVISOR_xsm_op(&op);
- if (rc)
- return rc;
- sid = op.u.peersid.sid;
- op.cmd = FLASK_SID_TO_CONTEXT;
- op.u.sid_context.sid = sid;
- op.u.sid_context.size = size;
- set_xen_guest_handle(op.u.sid_context.context, ctx);
- rc = HYPERVISOR_xsm_op(&op);
- return rc;
-}
-
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Frame Buffer + Keyboard driver for Mini-OS.
- * Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008
- * Based on blkfront.c.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/fbif.h>
-#include <xen/io/protocols.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/fbfront.h>
-#include <mini-os/lib.h>
-
-DECLARE_WAIT_QUEUE_HEAD(kbdfront_queue);
-
-
-
-
-
-
-struct kbdfront_dev {
- domid_t dom;
-
- struct xenkbd_page *page;
- evtchn_port_t evtchn;
-
- char *nodename;
- char *backend;
-
- xenbus_event_queue events;
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-};
-
-void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
-#ifdef HAVE_LIBC
- struct kbdfront_dev *dev = data;
- int fd = dev->fd;
-
- if (fd != -1)
- files[fd].read = 1;
-#endif
- wake_up(&kbdfront_queue);
-}
-
-static void free_kbdfront(struct kbdfront_dev *dev)
-{
- mask_evtchn(dev->evtchn);
-
- free(dev->backend);
-
- free_page(dev->page);
-
- unbind_evtchn(dev->evtchn);
-
- free(dev->nodename);
- free(dev);
-}
-
-struct kbdfront_dev *init_kbdfront(char *_nodename, int abs_pointer)
-{
- xenbus_transaction_t xbt;
- char* err;
- char* message=NULL;
- struct xenkbd_page *s;
- int retry=0;
- char* msg = NULL;
- char* nodename = _nodename ? _nodename : "device/vkbd/0";
- struct kbdfront_dev *dev;
-
- char path[strlen(nodename) + strlen("/backend-id") + 1];
-
- printk("******************* KBDFRONT for %s **********\n\n\n", nodename);
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- dev->dom = xenbus_read_integer(path);
- evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn);
-
- dev->page = s = (struct xenkbd_page*) alloc_page();
- memset(s,0,PAGE_SIZE);
-
- dev->events = NULL;
-
- s->in_cons = s->in_prod = 0;
- s->out_cons = s->out_prod = 0;
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "page-ref","%lu", virt_to_mfn(s));
- if (err) {
- message = "writing page-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- if (abs_pointer) {
- err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1");
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
- if (err) {
- printk("error writing initialized: %s\n", err);
- free(err);
- }
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- if (msg) {
- printk("Error %s when reading the backend path %s\n", msg, path);
- goto error;
- }
-
- printk("backend at %s\n", dev->backend);
-
- {
- XenbusState state;
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char frontpath[strlen(nodename) + strlen("/state") + 1];
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
- err = NULL;
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateConnected)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (state != XenbusStateConnected) {
- printk("backend not available, state=%d\n", state);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
-
- printk("%s connected\n", dev->backend);
-
- snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
- if((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected))
- != NULL) {
- printk("error switching state: %s\n", err);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
- }
- unmask_evtchn(dev->evtchn);
-
- printk("************************** KBDFRONT\n");
-
- return dev;
-error:
- free(msg);
- free(err);
- free_kbdfront(dev);
- return NULL;
-}
-
-int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n)
-{
- struct xenkbd_page *page = dev->page;
- uint32_t prod, cons;
- int i;
-
-#ifdef HAVE_LIBC
- if (dev->fd != -1) {
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
- }
-#endif
-
- prod = page->in_prod;
-
- if (prod == page->in_cons)
- return 0;
-
- rmb(); /* ensure we see ring contents up to prod */
-
- for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++)
- memcpy(buf + i, &XENKBD_IN_RING_REF(page, cons), sizeof(*buf));
-
- mb(); /* ensure we got ring contents */
- page->in_cons = cons;
- notify_remote_via_evtchn(dev->evtchn);
-
-#ifdef HAVE_LIBC
- if (cons != prod && dev->fd != -1)
- /* still some events to read */
- files[dev->fd].read = 1;
-#endif
-
- return i;
-}
-
-
-void shutdown_kbdfront(struct kbdfront_dev *dev)
-{
- char* err = NULL, *err2;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/request-abs-pointer") + 1];
-
- printk("close kbd: backend at %s\n",dev->backend);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("shutdown_kbdfront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close_kbdfront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("shutdown_kbdfront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close_kbdfront;
- }
- state = xenbus_read_integer(path);
- while (state < XenbusStateClosed) {
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
- }
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
- printk("shutdown_kbdfront: error changing state to %d: %s\n",
- XenbusStateInitialising, err);
- goto close_kbdfront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
-
-close_kbdfront:
- free(err);
- err2 = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err2);
-
- snprintf(nodename, sizeof(nodename), "%s/page-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/request-abs-pointer", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
-
- if (!err)
- free_kbdfront(dev);
-}
-
-#ifdef HAVE_LIBC
-int kbdfront_open(struct kbdfront_dev *dev)
-{
- dev->fd = alloc_fd(FTYPE_KBD);
- printk("kbd_open(%s) -> %d\n", dev->nodename, dev->fd);
- files[dev->fd].kbd.dev = dev;
- return dev->fd;
-}
-#endif
-
-
-
-
-
-DECLARE_WAIT_QUEUE_HEAD(fbfront_queue);
-
-
-
-
-
-
-struct fbfront_dev {
- domid_t dom;
-
- struct xenfb_page *page;
- evtchn_port_t evtchn;
-
- char *nodename;
- char *backend;
- int request_update;
-
- int width;
- int height;
- int depth;
- int stride;
- int mem_length;
- int offset;
-
- xenbus_event_queue events;
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-};
-
-void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
-#ifdef HAVE_LIBC
- struct fbfront_dev *dev = data;
- int fd = dev->fd;
-
- if (fd != -1)
- files[fd].read = 1;
-#endif
- wake_up(&fbfront_queue);
-}
-
-static void free_fbfront(struct fbfront_dev *dev)
-{
- mask_evtchn(dev->evtchn);
-
- free(dev->backend);
-
- free_page(dev->page);
-
- unbind_evtchn(dev->evtchn);
-
- free(dev->nodename);
- free(dev);
-}
-
-int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n)
-{
- struct xenfb_page *page = dev->page;
- uint32_t prod, cons;
- int i;
-
-#ifdef HAVE_LIBC
- if (dev->fd != -1) {
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
- }
-#endif
-
- prod = page->in_prod;
-
- if (prod == page->in_cons)
- return 0;
-
- rmb(); /* ensure we see ring contents up to prod */
-
- for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++)
- memcpy(buf + i, &XENFB_IN_RING_REF(page, cons), sizeof(*buf));
-
- mb(); /* ensure we got ring contents */
- page->in_cons = cons;
- notify_remote_via_evtchn(dev->evtchn);
-
-#ifdef HAVE_LIBC
- if (cons != prod && dev->fd != -1)
- /* still some events to read */
- files[dev->fd].read = 1;
-#endif
-
- return i;
-}
-
-struct fbfront_dev *init_fbfront(char *_nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n)
-{
- xenbus_transaction_t xbt;
- char* err;
- char* message=NULL;
- struct xenfb_page *s;
- int retry=0;
- char* msg=NULL;
- int i, j;
- struct fbfront_dev *dev;
- int max_pd;
- unsigned long mapped;
- char* nodename = _nodename ? _nodename : "device/vfb/0";
-
- char path[strlen(nodename) + strlen("/backend-id") + 1];
-
- printk("******************* FBFRONT for %s **********\n\n\n", nodename);
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- dev->dom = xenbus_read_integer(path);
- evtchn_alloc_unbound(dev->dom, fbfront_handler, dev, &dev->evtchn);
-
- dev->page = s = (struct xenfb_page*) alloc_page();
- memset(s,0,PAGE_SIZE);
-
- s->in_cons = s->in_prod = 0;
- s->out_cons = s->out_prod = 0;
- dev->width = s->width = width;
- dev->height = s->height = height;
- dev->depth = s->depth = depth;
- dev->stride = s->line_length = stride;
- dev->mem_length = s->mem_length = n * PAGE_SIZE;
- dev->offset = 0;
- dev->events = NULL;
-
- max_pd = sizeof(s->pd) / sizeof(s->pd[0]);
- mapped = 0;
-
- for (i = 0; mapped < n && i < max_pd; i++) {
- unsigned long *pd = (unsigned long *) alloc_page();
- for (j = 0; mapped < n && j < PAGE_SIZE / sizeof(unsigned long); j++)
- pd[j] = mfns[mapped++];
- for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++)
- pd[j] = 0;
- s->pd[i] = virt_to_mfn(pd);
- }
- for ( ; i < max_pd; i++)
- s->pd[i] = 0;
-
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "page-ref","%lu", virt_to_mfn(s));
- if (err) {
- message = "writing page-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename, "protocol", "%s",
- XEN_IO_PROTO_ABI_NATIVE);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename, "feature-update", "1");
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
- if (err) {
- message = "switching state";
- goto abort_transaction;
- }
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- if (msg) {
- printk("Error %s when reading the backend path %s\n", msg, path);
- goto error;
- }
-
- printk("backend at %s\n", dev->backend);
-
- {
- XenbusState state;
- char path[strlen(dev->backend) + strlen("/request-update") + 1];
- char frontpath[strlen(nodename) + strlen("/state") + 1];
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
- err = NULL;
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateConnected)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (state != XenbusStateConnected) {
- printk("backend not available, state=%d\n", state);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
-
- printk("%s connected\n", dev->backend);
-
- snprintf(path, sizeof(path), "%s/request-update", dev->backend);
- dev->request_update = xenbus_read_integer(path);
-
- snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
- if ((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected))
- != NULL) {
- printk("error switching state: %s\n", err);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
- }
- unmask_evtchn(dev->evtchn);
-
- printk("************************** FBFRONT\n");
-
- return dev;
-
-error:
- free(msg);
- free(err);
- free_fbfront(dev);
- return NULL;
-}
-
-static void fbfront_out_event(struct fbfront_dev *dev, union xenfb_out_event *event)
-{
- struct xenfb_page *page = dev->page;
- uint32_t prod;
- DEFINE_WAIT(w);
-
- add_waiter(w, fbfront_queue);
- while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN)
- schedule();
- remove_waiter(w, fbfront_queue);
-
- prod = page->out_prod;
- mb(); /* ensure ring space available */
- XENFB_OUT_RING_REF(page, prod) = *event;
- wmb(); /* ensure ring contents visible */
- page->out_prod = prod + 1;
- notify_remote_via_evtchn(dev->evtchn);
-}
-
-void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height)
-{
- struct xenfb_update update;
-
- if (dev->request_update <= 0)
- return;
-
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (x + width > dev->width)
- width = dev->width - x;
-
- if (y < 0) {
- height += y;
- y = 0;
- }
- if (y + height > dev->height)
- height = dev->height - y;
-
- if (width <= 0 || height <= 0)
- return;
-
- update.type = XENFB_TYPE_UPDATE;
- update.x = x;
- update.y = y;
- update.width = width;
- update.height = height;
- fbfront_out_event(dev, (union xenfb_out_event *) &update);
-}
-
-void fbfront_resize(struct fbfront_dev *dev, int width, int height, int stride, int depth, int offset)
-{
- struct xenfb_resize resize;
-
- resize.type = XENFB_TYPE_RESIZE;
- dev->width = resize.width = width;
- dev->height = resize.height = height;
- dev->stride = resize.stride = stride;
- dev->depth = resize.depth = depth;
- dev->offset = resize.offset = offset;
- fbfront_out_event(dev, (union xenfb_out_event *) &resize);
-}
-
-void shutdown_fbfront(struct fbfront_dev *dev)
-{
- char* err = NULL, *err2;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/feature-update") + 1];
-
- printk("close fb: backend at %s\n",dev->backend);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("shutdown_fbfront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close_fbfront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("shutdown_fbfront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close_fbfront;
- }
- state = xenbus_read_integer(path);
- if (state < XenbusStateClosed) {
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
- }
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
- printk("shutdown_fbfront: error changing state to %d: %s\n",
- XenbusStateInitialising, err);
- goto close_fbfront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
-
-close_fbfront:
- free(err);
- err2 = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err2);
-
- snprintf(nodename, sizeof(nodename), "%s/page-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/protocol", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/feature-update", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
-
- if (!err)
- free_fbfront(dev);
-}
-
-#ifdef HAVE_LIBC
-int fbfront_open(struct fbfront_dev *dev)
-{
- dev->fd = alloc_fd(FTYPE_FB);
- printk("fb_open(%s) -> %d\n", dev->nodename, dev->fd);
- files[dev->fd].fb.dev = dev;
- return dev->fd;
-}
-#endif
-
+++ /dev/null
-/*
- * Manages grant mappings from other domains.
- *
- * Diego Ongaro <diego.ongaro@citrix.com>, July 2008
- *
- * Files of type FTYPE_GNTMAP contain a gntmap, which is an array of
- * (host address, grant handle) pairs. Grant handles come from a hypervisor map
- * operation and are needed for the corresponding unmap.
- *
- * This is a rather naive implementation in terms of performance. If we start
- * using it frequently, there's definitely some low-hanging fruit here.
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-#include <errno.h>
-#include <xen/grant_table.h>
-#include <inttypes.h>
-#include <mini-os/gntmap.h>
-
-//#define GNTMAP_DEBUG
-#ifdef GNTMAP_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(gntmap.c:%d): %s" _f "\n", __LINE__, __func__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-
-#define DEFAULT_MAX_GRANTS 128
-
-struct gntmap_entry {
- unsigned long host_addr;
- grant_handle_t handle;
-};
-
-static inline int
-gntmap_entry_used(struct gntmap_entry *entry)
-{
- return entry->host_addr != 0;
-}
-
-static struct gntmap_entry*
-gntmap_find_free_entry(struct gntmap *map)
-{
- int i;
-
- for (i = 0; i < map->nentries; i++) {
- if (!gntmap_entry_used(&map->entries[i]))
- return &map->entries[i];
- }
-
- DEBUG("(map=%p): all %d entries full",
- map, map->nentries);
- return NULL;
-}
-
-static struct gntmap_entry*
-gntmap_find_entry(struct gntmap *map, unsigned long addr)
-{
- int i;
-
- for (i = 0; i < map->nentries; i++) {
- if (map->entries[i].host_addr == addr)
- return &map->entries[i];
- }
- return NULL;
-}
-
-int
-gntmap_set_max_grants(struct gntmap *map, int count)
-{
- DEBUG("(map=%p, count=%d)", map, count);
-
- if (map->nentries != 0)
- return -EBUSY;
-
- map->entries = xmalloc_array(struct gntmap_entry, count);
- if (map->entries == NULL)
- return -ENOMEM;
-
- memset(map->entries, 0, sizeof(struct gntmap_entry) * count);
- map->nentries = count;
- return 0;
-}
-
-static int
-_gntmap_map_grant_ref(struct gntmap_entry *entry,
- unsigned long host_addr,
- uint32_t domid,
- uint32_t ref,
- int writable)
-{
- struct gnttab_map_grant_ref op;
- int rc;
-
- op.ref = (grant_ref_t) ref;
- op.dom = (domid_t) domid;
- op.host_addr = (uint64_t) host_addr;
- op.flags = GNTMAP_host_map;
- if (!writable)
- op.flags |= GNTMAP_readonly;
-
- rc = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- if (rc != 0 || op.status != GNTST_okay) {
- printk("GNTTABOP_map_grant_ref failed: "
- "returned %d, status %" PRId16 "\n",
- rc, op.status);
- return rc != 0 ? rc : op.status;
- }
-
- entry->host_addr = host_addr;
- entry->handle = op.handle;
- return 0;
-}
-
-static int
-_gntmap_unmap_grant_ref(struct gntmap_entry *entry)
-{
- struct gnttab_unmap_grant_ref op;
- int rc;
-
- op.host_addr = (uint64_t) entry->host_addr;
- op.dev_bus_addr = 0;
- op.handle = entry->handle;
-
- rc = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- if (rc != 0 || op.status != GNTST_okay) {
- printk("GNTTABOP_unmap_grant_ref failed: "
- "returned %d, status %" PRId16 "\n",
- rc, op.status);
- return rc != 0 ? rc : op.status;
- }
-
- entry->host_addr = 0;
- return 0;
-}
-
-int
-gntmap_munmap(struct gntmap *map, unsigned long start_address, int count)
-{
- int i, rc;
- struct gntmap_entry *ent;
-
- DEBUG("(map=%p, start_address=%lx, count=%d)",
- map, start_address, count);
-
- for (i = 0; i < count; i++) {
- ent = gntmap_find_entry(map, start_address + PAGE_SIZE * i);
- if (ent == NULL) {
- printk("gntmap: tried to munmap unknown page\n");
- return -EINVAL;
- }
-
- rc = _gntmap_unmap_grant_ref(ent);
- if (rc != 0)
- return rc;
- }
-
- return 0;
-}
-
-void*
-gntmap_map_grant_refs(struct gntmap *map,
- uint32_t count,
- uint32_t *domids,
- int domids_stride,
- uint32_t *refs,
- int writable)
-{
- unsigned long addr;
- struct gntmap_entry *ent;
- int i;
-
- DEBUG("(map=%p, count=%" PRIu32 ", "
- "domids=%p [%" PRIu32 "...], domids_stride=%d, "
- "refs=%p [%" PRIu32 "...], writable=%d)",
- map, count,
- domids, domids == NULL ? 0 : domids[0], domids_stride,
- refs, refs == NULL ? 0 : refs[0], writable);
-
- (void) gntmap_set_max_grants(map, DEFAULT_MAX_GRANTS);
-
- addr = allocate_ondemand((unsigned long) count, 1);
- if (addr == 0)
- return NULL;
-
- for (i = 0; i < count; i++) {
- ent = gntmap_find_free_entry(map);
- if (ent == NULL ||
- _gntmap_map_grant_ref(ent,
- addr + PAGE_SIZE * i,
- domids[i * domids_stride],
- refs[i],
- writable) != 0) {
-
- (void) gntmap_munmap(map, addr, i);
- return NULL;
- }
- }
-
- return (void*) addr;
-}
-
-void
-gntmap_init(struct gntmap *map)
-{
- DEBUG("(map=%p)", map);
- map->nentries = 0;
- map->entries = NULL;
-}
-
-void
-gntmap_fini(struct gntmap *map)
-{
- struct gntmap_entry *ent;
- int i;
-
- DEBUG("(map=%p)", map);
-
- for (i = 0; i < map->nentries; i++) {
- ent = &map->entries[i];
- if (gntmap_entry_used(ent))
- (void) _gntmap_unmap_grant_ref(ent);
- }
-
- xfree(map->entries);
- map->entries = NULL;
- map->nentries = 0;
-}
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2006 - Cambridge University
- ****************************************************************************
- *
- * File: gnttab.c
- * Author: Steven Smith (sos22@cam.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: July 2006
- *
- * Environment: Xen Minimal OS
- * Description: Simple grant tables implementation. About as stupid as it's
- * possible to be and still work.
- *
- ****************************************************************************
- */
-#include <mini-os/os.h>
-#include <mini-os/mm.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/semaphore.h>
-
-#define NR_RESERVED_ENTRIES 8
-
-/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
-#define NR_GRANT_FRAMES 4
-#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
-
-static grant_entry_t *gnttab_table;
-static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
-#ifdef GNT_DEBUG
-static char inuse[NR_GRANT_ENTRIES];
-#endif
-static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0);
-
-static void
-put_free_entry(grant_ref_t ref)
-{
- unsigned long flags;
- local_irq_save(flags);
-#ifdef GNT_DEBUG
- BUG_ON(!inuse[ref]);
- inuse[ref] = 0;
-#endif
- gnttab_list[ref] = gnttab_list[0];
- gnttab_list[0] = ref;
- local_irq_restore(flags);
- up(&gnttab_sem);
-}
-
-static grant_ref_t
-get_free_entry(void)
-{
- unsigned int ref;
- unsigned long flags;
- down(&gnttab_sem);
- local_irq_save(flags);
- ref = gnttab_list[0];
- BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
- gnttab_list[0] = gnttab_list[ref];
-#ifdef GNT_DEBUG
- BUG_ON(inuse[ref]);
- inuse[ref] = 1;
-#endif
- local_irq_restore(flags);
- return ref;
-}
-
-grant_ref_t
-gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
-{
- grant_ref_t ref;
-
- ref = get_free_entry();
- gnttab_table[ref].frame = frame;
- gnttab_table[ref].domid = domid;
- wmb();
- readonly *= GTF_readonly;
- gnttab_table[ref].flags = GTF_permit_access | readonly;
-
- return ref;
-}
-
-grant_ref_t
-gnttab_grant_transfer(domid_t domid, unsigned long pfn)
-{
- grant_ref_t ref;
-
- ref = get_free_entry();
- gnttab_table[ref].frame = pfn;
- gnttab_table[ref].domid = domid;
- wmb();
- gnttab_table[ref].flags = GTF_accept_transfer;
-
- return ref;
-}
-
-int
-gnttab_end_access(grant_ref_t ref)
-{
- uint16_t flags, nflags;
-
- BUG_ON(ref >= NR_GRANT_ENTRIES || ref < NR_RESERVED_ENTRIES);
-
- nflags = gnttab_table[ref].flags;
- do {
- if ((flags = nflags) & (GTF_reading|GTF_writing)) {
- printk("WARNING: g.e. still in use! (%x)\n", flags);
- return 0;
- }
- } while ((nflags = synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)) !=
- flags);
-
- put_free_entry(ref);
- return 1;
-}
-
-unsigned long
-gnttab_end_transfer(grant_ref_t ref)
-{
- unsigned long frame;
- uint16_t flags;
-
- BUG_ON(ref >= NR_GRANT_ENTRIES || ref < NR_RESERVED_ENTRIES);
-
- while (!((flags = gnttab_table[ref].flags) & GTF_transfer_committed)) {
- if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0) == flags) {
- printk("Release unused transfer grant.\n");
- put_free_entry(ref);
- return 0;
- }
- }
-
- /* If a transfer is in progress then wait until it is completed. */
- while (!(flags & GTF_transfer_completed)) {
- flags = gnttab_table[ref].flags;
- }
-
- /* Read the frame number /after/ reading completion status. */
- rmb();
- frame = gnttab_table[ref].frame;
-
- put_free_entry(ref);
-
- return frame;
-}
-
-grant_ref_t
-gnttab_alloc_and_grant(void **map)
-{
- unsigned long mfn;
- grant_ref_t gref;
-
- *map = (void *)alloc_page();
- mfn = virt_to_mfn(*map);
- gref = gnttab_grant_access(0, mfn, 0);
- return gref;
-}
-
-static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
-
-const char *
-gnttabop_error(int16_t status)
-{
- status = -status;
- if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
- return "bad status";
- else
- return gnttabop_error_msgs[status];
-}
-
-void
-init_gnttab(void)
-{
- int i;
-
-#ifdef GNT_DEBUG
- memset(inuse, 1, sizeof(inuse));
-#endif
- for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
- put_free_entry(i);
-
- gnttab_table = arch_init_gnttab(NR_GRANT_FRAMES);
- printk("gnttab_table mapped at %p.\n", gnttab_table);
-}
-
-void
-fini_gnttab(void)
-{
- struct gnttab_setup_table setup;
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = 0;
-
- HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
-}
+++ /dev/null
-/******************************************************************************
- * hypervisor.c
- *
- * Communication to/from hypervisor.
- *
- * Copyright (c) 2002-2003, K A Fraser
- * Copyright (c) 2005, Grzegorz Milos, gm281@cam.ac.uk,Intel Research Cambridge
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/events.h>
-
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- ~(sh)->evtchn_mask[idx])
-
-int in_callback;
-
-void do_hypervisor_callback(struct pt_regs *regs)
-{
- unsigned long l1, l2, l1i, l2i;
- unsigned int port;
- int cpu = 0;
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
-
- in_callback = 1;
-
- vcpu_info->evtchn_upcall_pending = 0;
- /* NB x86. No need for a barrier here -- XCHG is a barrier on x86. */
-#if !defined(__i386__) && !defined(__x86_64__)
- /* Clear master flag /before/ clearing selector flag. */
- wmb();
-#endif
- l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
- while ( l1 != 0 )
- {
- l1i = __ffs(l1);
- l1 &= ~(1UL << l1i);
-
- while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 )
- {
- l2i = __ffs(l2);
- l2 &= ~(1UL << l2i);
-
- port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
- do_event(port, regs);
- }
- }
-
- in_callback = 0;
-}
-
-void force_evtchn_callback(void)
-{
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- int save;
-#endif
- vcpu_info_t *vcpu;
- vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- save = vcpu->evtchn_upcall_mask;
-#endif
-
- while (vcpu->evtchn_upcall_pending) {
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- vcpu->evtchn_upcall_mask = 1;
-#endif
- barrier();
- do_hypervisor_callback(NULL);
- barrier();
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- vcpu->evtchn_upcall_mask = save;
- barrier();
-#endif
- };
-}
-
-inline void mask_evtchn(uint32_t port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_set_bit(port, &s->evtchn_mask[0]);
-}
-
-inline void unmask_evtchn(uint32_t port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
-
- synch_clear_bit(port, &s->evtchn_mask[0]);
-
- /*
- * The following is basically the equivalent of 'hw_resend_irq'. Just like
- * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
- */
- if ( synch_test_bit (port, &s->evtchn_pending[0]) &&
- !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8),
- &vcpu_info->evtchn_pending_sel) )
- {
- vcpu_info->evtchn_upcall_pending = 1;
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- if ( !vcpu_info->evtchn_upcall_mask )
-#endif
- force_evtchn_callback();
- }
-}
-
-inline void clear_evtchn(uint32_t port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_clear_bit(port, &s->evtchn_pending[0]);
-}
+++ /dev/null
-/*
- * lwip/arch/cc.h
- *
- * Compiler-specific types and macros for lwIP running on mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#ifndef __LWIP_ARCH_CC_H__
-#define __LWIP_ARCH_CC_H__
-
-/* Typedefs for the types used by lwip - */
-#include <mini-os/os.h>
-#include <mini-os/types.h>
-#include <time.h>
-typedef uint8_t u8_t;
-typedef int8_t s8_t;
-typedef uint16_t u16_t;
-typedef int16_t s16_t;
-typedef uint32_t u32_t;
-typedef int32_t s32_t;
-typedef uint64_t u64_t;
-typedef int64_t s64_t;
-typedef uintptr_t mem_ptr_t;
-
-typedef uint16_t u_short;
-
-/* Compiler hints for packing lwip's structures - */
-#define PACK_STRUCT_FIELD(_x) _x
-#define PACK_STRUCT_STRUCT __attribute__ ((packed))
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_END
-
-/* Platform specific diagnostic output - */
-
-extern void lwip_printk(char *fmt, ...);
-#define LWIP_PLATFORM_DIAG(_x) do { lwip_printk _x ; } while (0)
-
-extern void lwip_die(char *fmt, ...);
-#define LWIP_PLATFORM_ASSERT(_x) do { lwip_die(_x); } while(0)
-
-/* "lightweight" synchronization mechanisms - */
-/* SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. */
-/* SYS_ARCH_PROTECT(x) - enter protection mode. */
-/* SYS_ARCH_UNPROTECT(x) - leave protection mode. */
-
-/* If the compiler does not provide memset() this file must include a */
-/* definition of it, or include a file which defines it. */
-#include <mini-os/lib.h>
-
-/* This file must either include a system-local <errno.h> which defines */
-/* the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO */
-/* to make lwip/arch.h define the codes which are used throughout. */
-#include <errno.h>
-
-/* Not required by the docs, but needed for network-order calculations */
-#ifdef HAVE_LIBC
-#include <machine/endian.h>
-#ifndef BIG_ENDIAN
-#error endian.h does not define byte order
-#endif
-#else
-#include <endian.h>
-#endif
-
-#include <inttypes.h>
-#define S16_F PRIi16
-#define U16_F PRIu16
-#define X16_F PRIx16
-#define S32_F PRIi32
-#define U32_F PRIu32
-#define X32_F PRIx32
-
-#if 0
-#ifndef DBG_ON
-#define DBG_ON LWIP_DBG_ON
-#endif
-#define LWIP_DEBUG DBG_ON
-//#define IP_DEBUG DBG_ON
-#define TCP_DEBUG DBG_ON
-#define TCP_INPUT_DEBUG DBG_ON
-#define TCP_QLEN_DEBUG DBG_ON
-#define TCPIP_DEBUG DBG_ON
-#define DBG_TYPES_ON DBG_ON
-#endif
-
-#endif /* __LWIP_ARCH_CC_H__ */
+++ /dev/null
-/*
- * lwip/arch/perf.h
- *
- * Arch-specific performance measurement for lwIP running on mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#ifndef __LWIP_ARCH_PERF_H__
-#define __LWIP_ARCH_PERF_H__
-
-#define PERF_START do { } while(0)
-#define PERF_STOP(_x) do { (void)(_x); } while (0)
-
-#endif /* __LWIP_ARCH_PERF_H__ */
+++ /dev/null
-/*
- * lwip/arch/sys_arch.h
- *
- * Arch-specific semaphores and mailboxes for lwIP running on mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#ifndef __LWIP_ARCH_SYS_ARCH_H__
-#define __LWIP_ARCH_SYS_ARCH_H__
-
-#include <mini-os/os.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/semaphore.h>
-
-typedef struct semaphore *sys_sem_t;
-#define SYS_SEM_NULL ((sys_sem_t) NULL)
-
-struct mbox {
- int count;
- void **messages;
- struct semaphore read_sem;
- struct semaphore write_sem;
- int writer;
- int reader;
-};
-
-typedef struct mbox *sys_mbox_t;
-#define SYS_MBOX_NULL ((sys_mbox_t) 0)
-
-typedef struct thread *sys_thread_t;
-
-typedef unsigned long sys_prot_t;
-
-#endif /*__LWIP_ARCH_SYS_ARCH_H__ */
+++ /dev/null
-#ifndef ARCH_ENDIAN_H
-#error "Do not include arch_endian by itself, include endian.h"
-#else
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-#endif
+++ /dev/null
-#ifndef __ARCH_LIMITS_H__
-#define __ARCH_LIMITS_H__
-
-#include <mm.h>
-
-#define __STACK_SIZE_PAGE_ORDER 2
-#define __STACK_SIZE (4 * PAGE_SIZE)
-
-#endif
+++ /dev/null
-#ifndef _ARCH_MM_H_
-#define _ARCH_MM_H_
-
-typedef uint64_t paddr_t;
-
-extern char _text, _etext, _erodata, _edata, _end, __bss_start;
-extern int _boot_stack[];
-extern int _boot_stack_end[];
-extern uint32_t physical_address_offset; /* Add this to a virtual address to get the physical address (wraps at 4GB) */
-
-#define PAGE_SHIFT 12
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#define L1_PAGETABLE_SHIFT 12
-
-#define to_phys(x) (((paddr_t)(x)+physical_address_offset) & 0xffffffff)
-#define to_virt(x) ((void *)(((x)-physical_address_offset) & 0xffffffff))
-
-#define PFN_UP(x) (unsigned long)(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
-#define PFN_DOWN(x) (unsigned long)((x) >> L1_PAGETABLE_SHIFT)
-#define PFN_PHYS(x) ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
-#define PHYS_PFN(x) (unsigned long)((x) >> L1_PAGETABLE_SHIFT)
-
-#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
-#define virt_to_mfn(_virt) (PFN_DOWN(to_phys(_virt)))
-#define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn)))
-#define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn)))
-
-#define mfn_to_pfn(x) (x)
-#define pfn_to_mfn(x) (x)
-
-#define virtual_to_mfn(_virt) virt_to_mfn(_virt)
-
-// FIXME
-#define map_frames(f, n) (NULL)
-
-#endif
+++ /dev/null
-#ifndef __ARCH_SCHED_H__
-#define __ARCH_SCHED_H__
-
-#include "arch_limits.h"
-
-static inline struct thread* get_current(void)
-{
- struct thread **current;
- unsigned long sp;
- __asm__ __volatile__ ("mov %0, sp":"=r"(sp));
- current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1));
- return *current;
-}
-
-void __arch_switch_threads(unsigned long *prevctx, unsigned long *nextctx);
-
-#define arch_switch_threads(prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp)
-
-#endif /* __ARCH_SCHED_H__ */
+++ /dev/null
-#ifndef __ARCH_ASM_SPINLOCK_H
-#define __ARCH_ASM_SPINLOCK_H
-
-#include "os.h"
-
-#define ARCH_SPIN_LOCK_UNLOCKED { 1 }
-
-/*
- * Simple spin lock operations. There are two variants, one clears IRQ's
- * on the local processor, one does not.
- *
- * We make no fairness assumptions. They have a cost.
- */
-
-#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0)
-#define arch_spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-
-static inline void _raw_spin_unlock(spinlock_t *lock)
-{
- xchg(&lock->slock, 1);
-}
-
-static inline int _raw_spin_trylock(spinlock_t *lock)
-{
- return xchg(&lock->slock, 0) != 0 ? 1 : 0;
-}
-
-static inline void _raw_spin_lock(spinlock_t *lock)
-{
- volatile int was_locked;
- do {
- was_locked = xchg(&lock->slock, 0) == 0 ? 1 : 0;
- } while(was_locked);
-}
-
-#endif
+++ /dev/null
-#define __WORDSIZE 32
+++ /dev/null
-void gic_init(void);
+++ /dev/null
-/******************************************************************************
- * hypercall-arm.h
- *
- * Copied from XenLinux.
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * 64-bit updates:
- * Benjamin Liu <benjamin.liu@intel.com>
- * Jun Nakajima <jun.nakajima@intel.com>
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef __HYPERCALL_ARM_H__
-#define __HYPERCALL_ARM_H__
-
-#include <xen/xen.h>
-#include <xen/sched.h>
-#include <xen/xsm/flask_op.h>
-#include <mini-os/mm.h>
-
-int
-HYPERVISOR_sched_op(
- int cmd, void *arg);
-
-static inline int
-HYPERVISOR_shutdown(
- unsigned int reason)
-{
- struct sched_shutdown shutdown = { .reason = reason };
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &shutdown);
-}
-
-int
-HYPERVISOR_memory_op(
- unsigned int cmd, void *arg);
-
-int
-HYPERVISOR_event_channel_op(
- int cmd, void *op);
-
-int
-HYPERVISOR_xen_version(
- int cmd, void *arg);
-
-int
-HYPERVISOR_console_io(
- int cmd, int count, char *str);
-
-int
-HYPERVISOR_physdev_op(
- void *physdev_op);
-
-int
-HYPERVISOR_grant_table_op(
- unsigned int cmd, void *uop, unsigned int count);
-
-int
-HYPERVISOR_vcpu_op(
- int cmd, int vcpuid, void *extra_args);
-
-int
-HYPERVISOR_sysctl(
- unsigned long op);
-
-int
-HYPERVISOR_domctl(
- unsigned long op);
-
-int
-HYPERVISOR_hvm_op(
- unsigned long op, void *arg);
-
-int
-HYPERVISOR_xsm_op(
- struct xen_flask_op *);
-
-#endif /* __HYPERCALL_ARM_H__ */
+++ /dev/null
-#ifndef _OS_H_
-#define _OS_H_
-
-#ifndef __ASSEMBLY__
-
-#include <mini-os/hypervisor.h>
-#include <mini-os/types.h>
-#include <mini-os/compiler.h>
-#include <mini-os/kernel.h>
-#include <xen/xen.h>
-
-void arch_fini(void);
-void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
-
-extern void *device_tree;
-
-#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined instruction; will call our fault handler. */
-
-#define smp_processor_id() 0
-
-#define barrier() __asm__ __volatile__("": : :"memory")
-
-extern shared_info_t *HYPERVISOR_shared_info;
-
-// disable interrupts
-static inline void local_irq_disable(void) {
- __asm__ __volatile__("cpsid i":::"memory");
-}
-
-// enable interrupts
-static inline void local_irq_enable(void) {
- __asm__ __volatile__("cpsie i":::"memory");
-}
-
-#define local_irq_save(x) { \
- __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory"); \
-}
-
-#define local_irq_restore(x) { \
- __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory"); \
-}
-
-#define local_save_flags(x) { \
- __asm__ __volatile__("mrs %0, cpsr":"=r"(x)::"memory"); \
-}
-
-static inline int irqs_disabled(void) {
- int x;
- local_save_flags(x);
- return x & 0x80;
-}
-
-/* We probably only need "dmb" here, but we'll start by being paranoid. */
-#define mb() __asm__("dsb":::"memory");
-#define rmb() __asm__("dsb":::"memory");
-#define wmb() __asm__("dsb":::"memory");
-
-/************************** arm *******************************/
-#ifdef __INSIDE_MINIOS__
-#if defined (__arm__)
-#define xchg(ptr,v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST)
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- *
- * This operation is atomic.
- * If you need a memory barrier, use synch_test_and_clear_bit instead.
- */
-static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
-{
- uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
- uint8_t bit = 1 << (nr & 7);
- uint8_t orig;
-
- orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_RELAXED);
-
- return (orig & bit) != 0;
-}
-
-/**
- * Atomically set a bit and return the old value.
- * Similar to test_and_clear_bit.
- */
-static __inline__ int test_and_set_bit(int nr, volatile void *base)
-{
- uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
- uint8_t bit = 1 << (nr & 7);
- uint8_t orig;
-
- orig = __atomic_fetch_or(byte, bit, __ATOMIC_RELAXED);
-
- return (orig & bit) != 0;
-}
-
-/**
- * Test whether a bit is set. */
-static __inline__ int test_bit(int nr, const volatile unsigned long *addr)
-{
- const uint8_t *ptr = (const uint8_t *) addr;
- return ((1 << (nr & 7)) & (ptr[nr >> 3])) != 0;
-}
-
-/**
- * Atomically set a bit in memory (like test_and_set_bit but discards result).
- */
-static __inline__ void set_bit(int nr, volatile unsigned long *addr)
-{
- test_and_set_bit(nr, addr);
-}
-
-/**
- * Atomically clear a bit in memory (like test_and_clear_bit but discards result).
- */
-static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
-{
- test_and_clear_bit(nr, addr);
-}
-
-/**
- * __ffs - find first (lowest) set bit in word.
- * @word: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static __inline__ unsigned long __ffs(unsigned long word)
-{
- int clz;
-
- /* xxxxx10000 = word
- * xxxxx01111 = word - 1
- * 0000011111 = word ^ (word - 1)
- * 4 = 31 - clz(word ^ (word - 1))
- */
-
- __asm__ (
- "sub r0, %[word], #1\n"
- "eor r0, r0, %[word]\n"
- "clz %[clz], r0\n":
- /* Outputs: */
- [clz] "=r"(clz):
- /* Inputs: */
- [word] "r"(word):
- /* Clobbers: */
- "r0");
-
- return 31 - clz;
-}
-
-#else /* ifdef __arm__ */
-#error "Unsupported architecture"
-#endif
-#endif /* ifdef __INSIDE_MINIOS */
-
-/********************* common arm32 and arm64 ****************************/
-
-/* If *ptr == old, then store new there (and return new).
- * Otherwise, return the old value.
- * Atomic. */
-#define synch_cmpxchg(ptr, old, new) \
-({ __typeof__(*ptr) stored = old; \
- __atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \
-})
-
-/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */
-static __inline__ int synch_test_and_clear_bit(int nr, volatile void *addr)
-{
- uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
- uint8_t bit = 1 << (nr & 7);
- uint8_t orig;
-
- orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST);
-
- return (orig & bit) != 0;
-}
-
-/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */
-static __inline__ int synch_test_and_set_bit(int nr, volatile void *base)
-{
- uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
- uint8_t bit = 1 << (nr & 7);
- uint8_t orig;
-
- orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST);
-
- return (orig & bit) != 0;
-}
-
-/* As set_bit, but using __ATOMIC_SEQ_CST */
-static __inline__ void synch_set_bit(int nr, volatile void *addr)
-{
- synch_test_and_set_bit(nr, addr);
-}
-
-/* As clear_bit, but using __ATOMIC_SEQ_CST */
-static __inline__ void synch_clear_bit(int nr, volatile void *addr)
-{
- synch_test_and_clear_bit(nr, addr);
-}
-
-/* As test_bit, but with a following memory barrier. */
-static __inline__ int synch_test_bit(int nr, volatile void *addr)
-{
- int result;
- result = test_bit(nr, addr);
- barrier();
- return result;
-}
-
-#endif /* not assembly */
-
-#endif
+++ /dev/null
-#ifndef _TRAPS_H_
-#define _TRAPS_H_
-
-struct pt_regs {
- unsigned long r0;
- unsigned long r1;
- unsigned long r2;
- unsigned long r3;
- unsigned long r4;
- unsigned long r5;
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r9;
- unsigned long r10;
- unsigned long r11;
- unsigned long r12;
-};
-
-#endif
+++ /dev/null
-#include <mini-os/wait.h>
-#include <xen/io/blkif.h>
-#include <mini-os/types.h>
-struct blkfront_dev;
-struct blkfront_aiocb
-{
- struct blkfront_dev *aio_dev;
- uint8_t *aio_buf;
- size_t aio_nbytes;
- off_t aio_offset;
- size_t total_bytes;
- uint8_t is_write;
- void *data;
-
- grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
- int n;
-
- void (*aio_cb)(struct blkfront_aiocb *aiocb, int ret);
-};
-struct blkfront_info
-{
- uint64_t sectors;
- unsigned sector_size;
- int mode;
- int info;
- int barrier;
- int flush;
-};
-struct blkfront_dev *init_blkfront(char *nodename, struct blkfront_info *info);
-#ifdef HAVE_LIBC
-#include <sys/stat.h>
-/* POSIX IO functions:
- * use blkfront_open() to get a file descriptor to the block device
- * Don't use the other blkfront posix functions here directly, instead use
- * read(), write(), lseek() and fstat() on the file descriptor
- */
-int blkfront_open(struct blkfront_dev *dev);
-int blkfront_posix_rwop(int fd, uint8_t* buf, size_t count, int write);
-#define blkfront_posix_write(fd, buf, count) blkfront_posix_rwop(fd, (uint8_t*)buf, count, 1)
-#define blkfront_posix_read(fd, buf, count) blkfront_posix_rwop(fd, (uint8_t*)buf, count, 0)
-int blkfront_posix_fstat(int fd, struct stat* buf);
-#endif
-void blkfront_aio(struct blkfront_aiocb *aiocbp, int write);
-#define blkfront_aio_read(aiocbp) blkfront_aio(aiocbp, 0)
-#define blkfront_aio_write(aiocbp) blkfront_aio(aiocbp, 1)
-void blkfront_io(struct blkfront_aiocb *aiocbp, int write);
-#define blkfront_read(aiocbp) blkfront_io(aiocbp, 0)
-#define blkfront_write(aiocbp) blkfront_io(aiocbp, 1)
-void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op);
-int blkfront_aio_poll(struct blkfront_dev *dev);
-void blkfront_sync(struct blkfront_dev *dev);
-void shutdown_blkfront(struct blkfront_dev *dev);
-
-extern struct wait_queue_head blkfront_queue;
+++ /dev/null
-#ifndef MINIOS_BYTEORDER_H
-#define MINIOS_BYTEORDER_H
-
-#include <mini-os/byteswap.h>
-#include <mini-os/endian.h>
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define be16_to_cpu(v) bswap_16(v)
-#define be32_to_cpu(v) bswap_32(v)
-#define be64_to_cpu(v) bswap_64(v)
-
-#define le16_to_cpu(v) (v)
-#define le32_to_cpu(v) (v)
-#define le64_to_cpu(v) (v)
-
-#else /*__BIG_ENDIAN*/
-#define be16_to_cpu(v) (v)
-#define be32_to_cpu(v) (v)
-#define be64_to_cpu(v) (v)
-
-#define le16_to_cpu(v) bswap_16(v)
-#define le32_to_cpu(v) bswap_32(v)
-#define le64_to_cpu(v) bswap_64(v)
-
-#endif
-
-#define cpu_to_be16(v) be16_to_cpu(v)
-#define cpu_to_be32(v) be32_to_cpu(v)
-#define cpu_to_be64(v) be64_to_cpu(v)
-
-#define cpu_to_le16(v) le16_to_cpu(v)
-#define cpu_to_le32(v) le32_to_cpu(v)
-#define cpu_to_le64(v) le64_to_cpu(v)
-
-
-#endif
+++ /dev/null
-#ifndef _BYTESWAP_H_
-#define _BYTESWAP_H_
-
-/* Unfortunately not provided by newlib. */
-
-#include <mini-os/types.h>
-
-#define bswap_16(x) ((uint16_t)( \
- (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
-
-/* Use gcc optimized versions if they exist */
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
-#define bswap_32(v) __builtin_bswap32(v)
-#define bswap_64(v) __builtin_bswap64(v)
-#else
-
-#define bswap_32(x) ((uint32_t)( \
- (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
-
-#define bswap_64(x) ((uint64_t)( \
- (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
- (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
- (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
- (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
- (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
- (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
- (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
- (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
-
-#endif
-
-
-
-
-#endif /* _BYTESWAP_H */
+++ /dev/null
-#ifndef __MINIOS_COMPILER_H_
-#define __MINIOS_COMPILER_H_
-
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
-#endif
-#define unlikely(x) __builtin_expect(!!(x),0)
-#define likely(x) __builtin_expect(!!(x),1)
-
-#endif /* __MINIOS_COMPILER_H_ */
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2006 - Grzegorz Milos - Cambridge University
- ****************************************************************************
- *
- * File: console.h
- * Author: Grzegorz Milos
- * Changes:
- *
- * Date: Mar 2006
- *
- * Environment: Xen Minimal OS
- * Description: Console interface.
- *
- * Handles console I/O. Defines printk.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef _LIB_CONSOLE_H_
-#define _LIB_CONSOLE_H_
-
-#include <mini-os/os.h>
-#include <mini-os/traps.h>
-#include <mini-os/types.h>
-#include <xen/grant_table.h>
-#include <xenbus.h>
-#include <xen/io/console.h>
-#include <stdarg.h>
-
-struct consfront_dev {
- domid_t dom;
-
- struct xencons_interface *ring;
- grant_ref_t ring_ref;
- evtchn_port_t evtchn;
-
- char *nodename;
- char *backend;
-
- xenbus_event_queue events;
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-};
-
-
-
-void print(int direct, const char *fmt, va_list args);
-void printk(const char *fmt, ...);
-void xprintk(const char *fmt, ...);
-
-#define tprintk(_fmt, _args...) printk("[%s] " _fmt, current->name, ##_args)
-
-void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
-void xencons_tx(void);
-
-void init_console(void);
-void console_print(struct consfront_dev *dev, char *data, int length);
-void fini_console(struct consfront_dev *dev);
-
-/* Low level functions defined in xencons_ring.c */
-extern struct wait_queue_head console_queue;
-struct consfront_dev *xencons_ring_init(void);
-struct consfront_dev *init_consfront(char *_nodename);
-int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len);
-int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len);
-int xencons_ring_avail(struct consfront_dev *dev);
-int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len);
-void free_consfront(struct consfront_dev *dev);
-
-#endif /* _LIB_CONSOLE_H_ */
+++ /dev/null
-#ifndef _CTYPE_H
-#define _CTYPE_H
-
-#ifdef HAVE_LIBC
-#include_next <ctype.h>
-#else
-/*
- * NOTE! This ctype does not handle EOF like the standard C
- * library is required to.
- */
-
-#define _U 0x01 /* upper */
-#define _L 0x02 /* lower */
-#define _D 0x04 /* digit */
-#define _C 0x08 /* cntrl */
-#define _P 0x10 /* punct */
-#define _S 0x20 /* white space (space/lf/tab) */
-#define _X 0x40 /* hex digit */
-#define _SP 0x80 /* hard space (0x20) */
-
-
-extern unsigned char _ctype[];
-
-#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
-
-#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
-#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
-#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
-#define isdigit(c) ((__ismask(c)&(_D)) != 0)
-#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
-#define islower(c) ((__ismask(c)&(_L)) != 0)
-#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
-#define ispunct(c) ((__ismask(c)&(_P)) != 0)
-#define isspace(c) ((__ismask(c)&(_S)) != 0)
-#define isupper(c) ((__ismask(c)&(_U)) != 0)
-#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
-
-#define isascii(c) (((unsigned char)(c))<=0x7f)
-#define toascii(c) (((unsigned char)(c))&0x7f)
-
-static inline unsigned char __tolower(unsigned char c)
-{
- if (isupper(c))
- c -= 'A'-'a';
- return c;
-}
-
-static inline unsigned char __toupper(unsigned char c)
-{
- if (islower(c))
- c -= 'a'-'A';
- return c;
-}
-
-#define tolower(c) __tolower(c)
-#define toupper(c) __toupper(c)
-
-#endif
-
-#endif
+++ /dev/null
-#ifndef _ENDIAN_H_
-#define _ENDIAN_H_
-
-#define __LITTLE_ENDIAN 1234
-#define __BIG_ENDIAN 4321
-#define __PDP_ENDIAN 3412
-
-#define ARCH_ENDIAN_H
-/* This will define __BYTE_ORDER for the current arch */
-#include <arch_endian.h>
-#undef ARCH_ENDIAN_H
-
-#include <arch_wordsize.h>
-
-#define BYTE_ORDER __BYTE_ORDER
-#define BIG_ENDIAN __BIG_ENDIAN
-#define LITTLE_ENDIAN __LITTLE_ENDIAN
-
-#endif /* endian.h */
+++ /dev/null
-#ifndef _ERR_H
-#define _ERR_H
-
-#include <mini-os/errno.h>
-
-/*
- * Kernel pointers have redundant information, so we can use a
- * scheme where we can return either an error code or a dentry
- * pointer with the same return value.
- *
- * This should be a per-architecture thing, to allow different
- * error and pointer decisions.
- */
-#define IS_ERR_VALUE(x) ((x) > (unsigned long)-1000L)
-
-static inline void *ERR_PTR(long error)
-{
- return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
- return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
- return IS_ERR_VALUE((unsigned long)ptr);
-}
-
-#endif /* _LINUX_ERR_H */
+++ /dev/null
-#ifndef _ERRNO_BASE_H
-#define _ERRNO_BASE_H
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* I/O error */
-#define ENXIO 6 /* No such device or address */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file number */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* Try again */
-#define ENOMEM 12 /* Out of memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device or resource busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* No such device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* File table overflow */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Not a typewriter */
-#define ETXTBSY 26 /* Text file busy */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-#define EDOM 33 /* Math argument out of domain of func */
-#define ERANGE 34 /* Math result not representable */
-
-#endif
+++ /dev/null
-#ifndef _ERRNO_H
-#define _ERRNO_H
-
-#include <mini-os/errno-base.h>
-
-typedef int error_t;
-
-#define EDEADLK 35 /* Resource deadlock would occur */
-#define ENAMETOOLONG 36 /* File name too long */
-#define ENOLCK 37 /* No record locks available */
-#define ENOSYS 38 /* Function not implemented */
-#define ENOTEMPTY 39 /* Directory not empty */
-#define ELOOP 40 /* Too many symbolic links encountered */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define ENOMSG 42 /* No message of desired type */
-#define EIDRM 43 /* Identifier removed */
-#define ECHRNG 44 /* Channel number out of range */
-#define EL2NSYNC 45 /* Level 2 not synchronized */
-#define EL3HLT 46 /* Level 3 halted */
-#define EL3RST 47 /* Level 3 reset */
-#define ELNRNG 48 /* Link number out of range */
-#define EUNATCH 49 /* Protocol driver not attached */
-#define ENOCSI 50 /* No CSI structure available */
-#define EL2HLT 51 /* Level 2 halted */
-#define EBADE 52 /* Invalid exchange */
-#define EBADR 53 /* Invalid request descriptor */
-#define EXFULL 54 /* Exchange full */
-#define ENOANO 55 /* No anode */
-#define EBADRQC 56 /* Invalid request code */
-#define EBADSLT 57 /* Invalid slot */
-
-#define EDEADLOCK EDEADLK
-
-#define EBFONT 59 /* Bad font file format */
-#define ENOSTR 60 /* Device not a stream */
-#define ENODATA 61 /* No data available */
-#define ETIME 62 /* Timer expired */
-#define ENOSR 63 /* Out of streams resources */
-#define ENONET 64 /* Machine is not on the network */
-#define ENOPKG 65 /* Package not installed */
-#define EREMOTE 66 /* Object is remote */
-#define ENOLINK 67 /* Link has been severed */
-#define EADV 68 /* Advertise error */
-#define ESRMNT 69 /* Srmount error */
-#define ECOMM 70 /* Communication error on send */
-#define EPROTO 71 /* Protocol error */
-#define EMULTIHOP 72 /* Multihop attempted */
-#define EDOTDOT 73 /* RFS specific error */
-#define EBADMSG 74 /* Not a data message */
-#define EOVERFLOW 75 /* Value too large for defined data type */
-#define ENOTUNIQ 76 /* Name not unique on network */
-#define EBADFD 77 /* File descriptor in bad state */
-#define EREMCHG 78 /* Remote address changed */
-#define ELIBACC 79 /* Can not access a needed shared library */
-#define ELIBBAD 80 /* Accessing a corrupted shared library */
-#define ELIBSCN 81 /* .lib section in a.out corrupted */
-#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define EILSEQ 84 /* Illegal byte sequence */
-#define ERESTART 85 /* Interrupted system call should be restarted */
-#define ESTRPIPE 86 /* Streams pipe error */
-#define EUSERS 87 /* Too many users */
-#define ENOTSOCK 88 /* Socket operation on non-socket */
-#define EDESTADDRREQ 89 /* Destination address required */
-#define EMSGSIZE 90 /* Message too long */
-#define EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 92 /* Protocol not available */
-#define EPROTONOSUPPORT 93 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define ENOTSUP EOPNOTSUPP
-#define EPFNOSUPPORT 96 /* Protocol family not supported */
-#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define EADDRINUSE 98 /* Address already in use */
-#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define ENETDOWN 100 /* Network is down */
-#define ENETUNREACH 101 /* Network is unreachable */
-#define ENETRESET 102 /* Network dropped connection because of reset */
-#define ECONNABORTED 103 /* Software caused connection abort */
-#define ECONNRESET 104 /* Connection reset by peer */
-#define ENOBUFS 105 /* No buffer space available */
-#define EISCONN 106 /* Transport endpoint is already connected */
-#define ENOTCONN 107 /* Transport endpoint is not connected */
-#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define ETIMEDOUT 110 /* Connection timed out */
-#define ECONNREFUSED 111 /* Connection refused */
-#define EHOSTDOWN 112 /* Host is down */
-#define EHOSTUNREACH 113 /* No route to host */
-#define EALREADY 114 /* Operation already in progress */
-#define EINPROGRESS 115 /* Operation now in progress */
-#define ESTALE 116 /* Stale NFS file handle */
-#define EUCLEAN 117 /* Structure needs cleaning */
-#define ENOTNAM 118 /* Not a XENIX named type file */
-#define ENAVAIL 119 /* No XENIX semaphores available */
-#define EISNAM 120 /* Is a named type file */
-#define EREMOTEIO 121 /* Remote I/O error */
-#define EDQUOT 122 /* Quota exceeded */
-
-#define ENOMEDIUM 123 /* No medium found */
-#define EMEDIUMTYPE 124 /* Wrong medium type */
-#define ECANCELED 125 /* Operation Canceled */
-#define ENOKEY 126 /* Required key not available */
-#define EKEYEXPIRED 127 /* Key has expired */
-#define EKEYREVOKED 128 /* Key has been revoked */
-#define EKEYREJECTED 129 /* Key was rejected by service */
-
-/* for robust mutexes */
-#define EOWNERDEAD 130 /* Owner died */
-#define ENOTRECOVERABLE 131 /* State not recoverable */
-
-
-#define EFTYPE 132 /* Inappropriate file type or format */
-
-#ifdef HAVE_LIBC
-#include <mini-os/sched.h>
-extern int errno;
-#define ERRNO
-#define errno (get_current()->reent._errno)
-#endif
-
-#endif
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Reseach Cambridge
- ****************************************************************************
- *
- * File: events.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: Jul 2003, changes Jun 2005
- *
- * Environment: Xen Minimal OS
- * Description: Deals with events on the event channels
- *
- ****************************************************************************
- */
-
-#ifndef _EVENTS_H_
-#define _EVENTS_H_
-
-#include<mini-os/traps.h>
-#include<xen/event_channel.h>
-
-typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
-
-/* prototypes */
-void arch_init_events(void);
-
-/* Called by fini_events to close any ports opened by arch-specific code. */
-void arch_unbind_ports(void);
-
-void arch_fini_events(void);
-
-int do_event(evtchn_port_t port, struct pt_regs *regs);
-evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data);
-evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data);
-evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
- void *data);
-void unbind_evtchn(evtchn_port_t port);
-void init_events(void);
-int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
- void *data, evtchn_port_t *port);
-int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
- evtchn_handler_t handler, void *data,
- evtchn_port_t *local_port);
-int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size);
-void unbind_all_ports(void);
-
-static inline int notify_remote_via_evtchn(evtchn_port_t port)
-{
- evtchn_send_t op;
- op.port = port;
- return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
-}
-
-void fini_events(void);
-
-#endif /* _EVENTS_H_ */
+++ /dev/null
-#include <xen/io/kbdif.h>
-#include <xen/io/fbif.h>
-#include <mini-os/semaphore.h>
-#include <mini-os/wait.h>
-
-/* from <linux/input.h> */
-#ifndef BTN_LEFT
-#define BTN_LEFT 0x110
-#endif
-#ifndef BTN_RIGHT
-#define BTN_RIGHT 0x111
-#endif
-#ifndef BTN_MIDDLE
-#define BTN_MIDDLE 0x112
-#endif
-#ifndef KEY_Q
-#define KEY_Q 16
-#endif
-#ifndef KEY_MAX
-#define KEY_MAX 0x1ff
-#endif
-
-
-struct kbdfront_dev;
-struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer);
-#ifdef HAVE_LIBC
-int kbdfront_open(struct kbdfront_dev *dev);
-#endif
-
-int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n);
-extern struct wait_queue_head kbdfront_queue;
-
-void shutdown_kbdfront(struct kbdfront_dev *dev);
-
-
-struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n);
-#ifdef HAVE_LIBC
-int fbfront_open(struct fbfront_dev *dev);
-#endif
-
-int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n);
-extern struct wait_queue_head fbfront_queue;
-void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height);
-void fbfront_resize(struct fbfront_dev *dev, int width, int height, int stride, int depth, int offset);
-
-void shutdown_fbfront(struct fbfront_dev *dev);
+++ /dev/null
-#ifndef _I386_FCNTL_H
-#define _I386_FCNTL_H
-
-#ifdef HAVE_LIBC
-#include_next <fcntl.h>
-#else
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define FASYNC 020000 /* fcntl, for BSD compatibility */
-#define O_DIRECT 040000 /* direct disk access hint */
-#define O_LARGEFILE 0100000
-#define O_DIRECTORY 0200000 /* must be a directory */
-#define O_NOFOLLOW 0400000 /* don't follow links */
-#define O_NOATIME 01000000
-
-#define F_DUPFD 0 /* dup */
-#define F_GETFD 1 /* get close_on_exec */
-#define F_SETFD 2 /* set/clear close_on_exec */
-#define F_GETFL 3 /* get file->f_flags */
-#define F_SETFL 4 /* set file->f_flags */
-#define F_GETLK 5
-#define F_SETLK 6
-#define F_SETLKW 7
-
-#define F_SETOWN 8 /* for sockets. */
-#define F_GETOWN 9 /* for sockets. */
-#define F_SETSIG 10 /* for sockets. */
-#define F_GETSIG 11 /* for sockets. */
-
-#define F_GETLK64 12 /* using 'struct flock64' */
-#define F_SETLK64 13
-#define F_SETLKW64 14
-
-/* for F_[GET|SET]FL */
-#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
-
-/* for posix fcntl() and lockf() */
-#define F_RDLCK 0
-#define F_WRLCK 1
-#define F_UNLCK 2
-
-/* for old implementation of bsd flock () */
-#define F_EXLCK 4 /* or 3 */
-#define F_SHLCK 8 /* or 4 */
-
-/* for leases */
-#define F_INPROGRESS 16
-
-/* operations for bsd flock(), also used by the kernel implementation */
-#define LOCK_SH 1 /* shared lock */
-#define LOCK_EX 2 /* exclusive lock */
-#define LOCK_NB 4 /* or'd with one of the above to prevent
- blocking */
-#define LOCK_UN 8 /* remove lock */
-
-#define LOCK_MAND 32 /* This is a mandatory flock */
-#define LOCK_READ 64 /* ... Which allows concurrent read operations */
-#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
-#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
-
-/*
-struct flock {
- short l_type;
- short l_whence;
- off_t l_start;
- off_t l_len;
- pid_t l_pid;
-};
-
-struct flock64 {
- short l_type;
- short l_whence;
- loff_t l_start;
- loff_t l_len;
- pid_t l_pid;
-};
-
-#define F_LINUX_SPECIFIC_BASE 1024
-*/
-
-#endif
-
-int open(const char *path, int flags, ...) asm("open64");
-int fcntl(int fd, int cmd, ...);
-
-#endif
+++ /dev/null
-#ifndef __GNTMAP_H__
-#define __GNTMAP_H__
-
-#include <os.h>
-
-/*
- * Please consider struct gntmap opaque. If instead you choose to disregard
- * this message, I insist that you keep an eye out for raptors.
- */
-struct gntmap {
- int nentries;
- struct gntmap_entry *entries;
-};
-
-int
-gntmap_set_max_grants(struct gntmap *map, int count);
-
-int
-gntmap_munmap(struct gntmap *map, unsigned long start_address, int count);
-
-void*
-gntmap_map_grant_refs(struct gntmap *map,
- uint32_t count,
- uint32_t *domids,
- int domids_stride,
- uint32_t *refs,
- int writable);
-
-void
-gntmap_init(struct gntmap *map);
-
-void
-gntmap_fini(struct gntmap *map);
-
-#endif /* !__GNTMAP_H__ */
+++ /dev/null
-#ifndef __GNTTAB_H__
-#define __GNTTAB_H__
-
-#include <xen/grant_table.h>
-
-void init_gnttab(void);
-grant_ref_t gnttab_alloc_and_grant(void **map);
-grant_ref_t gnttab_grant_access(domid_t domid, unsigned long frame,
- int readonly);
-grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
-unsigned long gnttab_end_transfer(grant_ref_t gref);
-int gnttab_end_access(grant_ref_t ref);
-const char *gnttabop_error(int16_t status);
-void fini_gnttab(void);
-grant_entry_t *arch_init_gnttab(int nr_grant_frames);
-
-#endif /* !__GNTTAB_H__ */
+++ /dev/null
-/******************************************************************************
- * hypervisor.h
- *
- * Hypervisor handling.
- *
- *
- * Copyright (c) 2002, K A Fraser
- * Copyright (c) 2005, Grzegorz Milos
- * Updates: Aravindh Puthiyaparambil <aravindh.puthiyaparambil@unisys.com>
- */
-
-#ifndef _HYPERVISOR_H_
-#define _HYPERVISOR_H_
-
-#include <mini-os/types.h>
-#include <xen/xen.h>
-#if defined(__i386__)
-#include <hypercall-x86_32.h>
-#elif defined(__x86_64__)
-#include <hypercall-x86_64.h>
-#elif defined(__arm__) || defined(__aarch64__)
-#include <hypercall-arm.h>
-#else
-#error "Unsupported architecture"
-#endif
-#include <mini-os/traps.h>
-
-/*
- * a placeholder for the start of day information passed up from the hypervisor
- */
-union start_info_union
-{
- start_info_t start_info;
- char padding[512];
-};
-extern union start_info_union start_info_union;
-#define start_info (start_info_union.start_info)
-
-/* hypervisor.c */
-void force_evtchn_callback(void);
-void do_hypervisor_callback(struct pt_regs *regs);
-void mask_evtchn(uint32_t port);
-void unmask_evtchn(uint32_t port);
-void clear_evtchn(uint32_t port);
-
-extern int in_callback;
-
-#endif /* __HYPERVISOR_H__ */
+++ /dev/null
-/**
- * Copyright (C) 2009 Netronome Systems, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef _IOREMAP_H_
-#define _IOREMAP_H_
-
-void *ioremap(unsigned long phys_addr, unsigned long size);
-void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
-void iounmap(void *virt_addr, unsigned long size);
-
-#endif /* _IOREMAP_H_ */
-
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
+++ /dev/null
-#ifndef MINIOS_IORW_H
-#define MINIOS_IORW_H
-
-#include <mini-os/types.h>
-
-void iowrite8(volatile void* addr, uint8_t val);
-void iowrite16(volatile void* addr, uint16_t val);
-void iowrite32(volatile void* addr, uint32_t val);
-void iowrite64(volatile void* addr, uint64_t val);
-
-uint8_t ioread8(volatile void* addr);
-uint16_t ioread16(volatile void* addr);
-uint32_t ioread32(volatile void* addr);
-uint64_t ioread64(volatile void* addr);
-
-#endif
+++ /dev/null
-#ifndef _KERNEL_H_
-#define _KERNEL_H_
-
-void start_kernel(void);
-void do_exit(void) __attribute__((noreturn));
-void arch_do_exit(void);
-void stop_kernel(void);
-
-#endif /* _KERNEL_H_ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: lib.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes:
- *
- * Date: Aug 2003
- *
- * Environment: Xen Minimal OS
- * Description: Random useful library functions, from Linux'
- * include/linux/kernel.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _LIB_GPL_H_
-#define _LIB_GPL_H_
-
-#ifndef HAVE_LIBC
-/* printing */
-extern unsigned long simple_strtoul(const char *,char **,unsigned int);
-extern long simple_strtol(const char *,char **,unsigned int);
-extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
-extern long long simple_strtoll(const char *,char **,unsigned int);
-
-extern int sprintf(char * buf, const char * fmt, ...)
- __attribute__ ((format (printf, 2, 3)));
-extern int vsprintf(char *buf, const char *, va_list)
- __attribute__ ((format (printf, 2, 0)));
-extern int snprintf(char * buf, size_t size, const char * fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
- __attribute__ ((format (printf, 3, 0)));
-extern int scnprintf(char * buf, size_t size, const char * fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
- __attribute__ ((format (printf, 3, 0)));
-extern int sscanf(const char *, const char *, ...)
- __attribute__ ((format (scanf, 2, 3)));
-extern int vsscanf(const char *, const char *, va_list)
- __attribute__ ((format (scanf, 2, 0)));
-#endif
-
-#endif /* _LIB_GPL_H_ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: lib.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes:
- *
- * Date: Aug 2003
- *
- * Environment: Xen Minimal OS
- * Description: Random useful library functions, contains some freebsd stuff
- *
- ****************************************************************************
- * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $
- ****************************************************************************
- *
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _LIB_H_
-#define _LIB_H_
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <xen/xen.h>
-#include <xen/event_channel.h>
-#include "gntmap.h"
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); })
-#define BUILD_BUG_ON_ZERO(cond) \
- sizeof(struct { _Static_assert(!(cond), "!(" #cond ")"); })
-#else
-#define BUILD_BUG_ON_ZERO(cond) sizeof(struct { int:-!!(cond); })
-#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond))
-#endif
-
-#ifdef HAVE_LIBC
-#include <sys/queue.h>
-#include <stdio.h>
-#else
-#include <lib-gpl.h>
-#endif
-
-#ifdef HAVE_LIBC
-#include <string.h>
-#else
-/* string and memory manipulation */
-
-/*
- * From:
- * @(#)libkern.h 8.1 (Berkeley) 6/10/93
- * $FreeBSD$
- */
-int memcmp(const void *b1, const void *b2, size_t len);
-
-char *strcat(char * __restrict, const char * __restrict);
-int strcmp(const char *, const char *);
-char *strcpy(char * __restrict, const char * __restrict);
-
-char *strdup(const char *__restrict);
-
-size_t strlen(const char *);
-
-int strncmp(const char *, const char *, size_t);
-char *strncpy(char * __restrict, const char * __restrict, size_t);
-
-char *strstr(const char *, const char *);
-
-void *memset(void *, int, size_t);
-
-char *strchr(const char *p, int ch);
-char *strrchr(const char *p, int ch);
-
-/* From:
- * @(#)systm.h 8.7 (Berkeley) 3/29/95
- * $FreeBSD$
- */
-void *memcpy(void *to, const void *from, size_t len);
-
-size_t strnlen(const char *, size_t);
-#endif
-
-#include <mini-os/console.h>
-
-#define RAND_MIX 2654435769U
-
-int rand(void);
-
-#include <mini-os/xenbus.h>
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define ASSERT(x) \
-do { \
- if (!(x)) { \
- printk("ASSERTION FAILED: %s at %s:%d.\n", \
- # x , \
- __FILE__, \
- __LINE__); \
- BUG(); \
- } \
-} while(0)
-
-#define BUG_ON(x) ASSERT(!(x))
-
-/* Consistency check as much as possible. */
-void sanity_check(void);
-
-#ifdef HAVE_LIBC
-enum fd_type {
- FTYPE_NONE = 0,
- FTYPE_CONSOLE,
- FTYPE_FILE,
- FTYPE_XENBUS,
- FTYPE_XC,
- FTYPE_EVTCHN,
- FTYPE_GNTMAP,
- FTYPE_SOCKET,
- FTYPE_TAP,
- FTYPE_BLK,
- FTYPE_KBD,
- FTYPE_FB,
- FTYPE_MEM,
- FTYPE_SAVEFILE,
- FTYPE_TPMFRONT,
- FTYPE_TPM_TIS,
-};
-
-LIST_HEAD(evtchn_port_list, evtchn_port_info);
-
-struct evtchn_port_info {
- LIST_ENTRY(evtchn_port_info) list;
- evtchn_port_t port;
- unsigned long pending;
- int bound;
-};
-
-extern struct file {
- enum fd_type type;
- union {
- struct {
- /* lwIP fd */
- int fd;
- } socket;
- struct {
- /* FS import fd */
- int fd;
- off_t offset;
- } file;
- struct {
- struct evtchn_port_list ports;
- } evtchn;
- struct gntmap gntmap;
- struct {
- struct netfront_dev *dev;
- } tap;
- struct {
- struct blkfront_dev *dev;
- off_t offset;
- } blk;
- struct {
- struct kbdfront_dev *dev;
- } kbd;
- struct {
- struct fbfront_dev *dev;
- } fb;
- struct {
- struct consfront_dev *dev;
- } cons;
-#ifdef CONFIG_TPMFRONT
- struct {
- struct tpmfront_dev *dev;
- int respgot;
- off_t offset;
- } tpmfront;
-#endif
-#ifdef CONFIG_TPM_TIS
- struct {
- struct tpm_chip *dev;
- int respgot;
- off_t offset;
- } tpm_tis;
-#endif
-#ifdef CONFIG_XENBUS
- struct {
- /* To each xenbus FD is associated a queue of watch events for this
- * FD. */
- xenbus_event_queue events;
- } xenbus;
-#endif
- };
- int read; /* maybe available for read */
-} files[];
-
-int alloc_fd(enum fd_type type);
-void close_all_files(void);
-extern struct thread *main_thread;
-void sparse(unsigned long data, size_t size);
-#endif
-
-#endif /* _LIB_H_ */
+++ /dev/null
-#ifndef _LINUX_TYPES_H_
-#define _LINUX_TYPES_H_
-#include <mini-os/types.h>
-typedef uint64_t __u64;
-#endif /* _LINUX_TYPES_H_ */
+++ /dev/null
-/*
- * lwipopts.h
- *
- * Configuration for lwIP running on mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#ifndef __LWIP_LWIPOPTS_H__
-#define __LWIP_LWIPOPTS_H__
-
-#define SYS_LIGHTWEIGHT_PROT 1
-#define MEM_LIBC_MALLOC 1
-#define LWIP_TIMEVAL_PRIVATE 0
-#define LWIP_DHCP 1
-#define LWIP_COMPAT_SOCKETS 0
-#define LWIP_IGMP 1
-#define LWIP_USE_HEAP_FROM_INTERRUPT 1
-#define MEMP_NUM_SYS_TIMEOUT 10
-#define TCP_SND_BUF 3000
-#define TCP_MSS 1500
-
-#endif /* __LWIP_LWIPOPTS_H__ */
+++ /dev/null
-WARNING - DO NOT EDIT THINGS IN THIS DIRECTORY
-----------------------------------------------
-
-These files were obtained elsewhere and should only be updated by
-copying new versions from the source location, as documented below:
-
-bsd-COPYRIGHT
-bsd-sys-queue.h
-bsd-queue.3
-
- Obtained from the FreeBSD SVN using the following commands:
- svn co -r 221843 svn://svn.freebsd.org/base/head/sys/sys/
- svn co -r 221843 svn://svn.freebsd.org/base/head/share/man/man3
- svn cat -r 221843 http://svn.freebsd.org/base/head/COPYRIGHT >tools/libxl/external/bsd-COPYRIGHT
-
-Exceptions:
-
-README
-
- This file
-
-bsd-sys-queue-h-seddery
-
- Script to transform the above into a new namespace.
+++ /dev/null
-# $FreeBSD$
-# @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94
-
-The compilation of software known as FreeBSD is distributed under the
-following terms:
-
-Copyright (c) 1992-2011 The FreeBSD Project. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-The 4.4BSD and 4.4BSD-Lite software is distributed under the following
-terms:
-
-All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite
-Releases is copyrighted by The Regents of the University of California.
-
-Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
-This product includes software developed by the University of
-California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-The Institute of Electrical and Electronics Engineers and the American
-National Standards Committee X3, on Information Processing Systems have
-given us permission to reprint portions of their documentation.
-
-In the following statement, the phrase ``this text'' refers to portions
-of the system documentation.
-
-Portions of this text are reprinted and reproduced in electronic form in
-the second BSD Networking Software Release, from IEEE Std 1003.1-1988, IEEE
-Standard Portable Operating System Interface for Computer Environments
-(POSIX), copyright C 1988 by the Institute of Electrical and Electronics
-Engineers, Inc. In the event of any discrepancy between these versions
-and the original IEEE Standard, the original IEEE Standard is the referee
-document.
-
-In the following statement, the phrase ``This material'' refers to portions
-of the system documentation.
-
-This material is reproduced with permission from American National
-Standards Committee X3, on Information Processing Systems. Computer and
-Business Equipment Manufacturers Association (CBEMA), 311 First St., NW,
-Suite 500, Washington, DC 20001-2178. The developmental work of
-Programming Language C was completed by the X3J11 Technical Committee.
-
-The views and conclusions contained in the software and documentation are
-those of the authors and should not be interpreted as representing official
-policies, either expressed or implied, of the Regents of the University
-of California.
-
-
-NOTE: The copyright of UC Berkeley's Berkeley Software Distribution ("BSD")
-source has been updated. The copyright addendum may be found at
-ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change and is
-included below.
-
-July 22, 1999
-
-To All Licensees, Distributors of Any Version of BSD:
-
-As you know, certain of the Berkeley Software Distribution ("BSD") source
-code files require that further distributions of products containing all or
-portions of the software, acknowledge within their advertising materials
-that such products contain software developed by UC Berkeley and its
-contributors.
-
-Specifically, the provision reads:
-
-" * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors."
-
-Effective immediately, licensees and distributors are no longer required to
-include the acknowledgement within advertising materials. Accordingly, the
-foregoing paragraph of those BSD Unix files containing it is hereby deleted
-in its entirety.
-
-William Hoskins
-Director, Office of Technology Licensing
-University of California, Berkeley
+++ /dev/null
-.\" Copyright (c) 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
-.\" $FreeBSD$
-.\"
-.Dd May 13, 2011
-.Dt QUEUE 3
-.Os
-.Sh NAME
-.Nm SLIST_EMPTY ,
-.Nm SLIST_ENTRY ,
-.Nm SLIST_FIRST ,
-.Nm SLIST_FOREACH ,
-.Nm SLIST_FOREACH_SAFE ,
-.Nm SLIST_HEAD ,
-.Nm SLIST_HEAD_INITIALIZER ,
-.Nm SLIST_INIT ,
-.Nm SLIST_INSERT_AFTER ,
-.Nm SLIST_INSERT_HEAD ,
-.Nm SLIST_NEXT ,
-.Nm SLIST_REMOVE_AFTER ,
-.Nm SLIST_REMOVE_HEAD ,
-.Nm SLIST_REMOVE ,
-.Nm SLIST_SWAP ,
-.Nm STAILQ_CONCAT ,
-.Nm STAILQ_EMPTY ,
-.Nm STAILQ_ENTRY ,
-.Nm STAILQ_FIRST ,
-.Nm STAILQ_FOREACH ,
-.Nm STAILQ_FOREACH_SAFE ,
-.Nm STAILQ_HEAD ,
-.Nm STAILQ_HEAD_INITIALIZER ,
-.Nm STAILQ_INIT ,
-.Nm STAILQ_INSERT_AFTER ,
-.Nm STAILQ_INSERT_HEAD ,
-.Nm STAILQ_INSERT_TAIL ,
-.Nm STAILQ_LAST ,
-.Nm STAILQ_NEXT ,
-.Nm STAILQ_REMOVE_AFTER ,
-.Nm STAILQ_REMOVE_HEAD ,
-.Nm STAILQ_REMOVE ,
-.Nm STAILQ_SWAP ,
-.Nm LIST_EMPTY ,
-.Nm LIST_ENTRY ,
-.Nm LIST_FIRST ,
-.Nm LIST_FOREACH ,
-.Nm LIST_FOREACH_SAFE ,
-.Nm LIST_HEAD ,
-.Nm LIST_HEAD_INITIALIZER ,
-.Nm LIST_INIT ,
-.Nm LIST_INSERT_AFTER ,
-.Nm LIST_INSERT_BEFORE ,
-.Nm LIST_INSERT_HEAD ,
-.Nm LIST_NEXT ,
-.Nm LIST_REMOVE ,
-.Nm LIST_SWAP ,
-.Nm TAILQ_CONCAT ,
-.Nm TAILQ_EMPTY ,
-.Nm TAILQ_ENTRY ,
-.Nm TAILQ_FIRST ,
-.Nm TAILQ_FOREACH ,
-.Nm TAILQ_FOREACH_SAFE ,
-.Nm TAILQ_FOREACH_REVERSE ,
-.Nm TAILQ_FOREACH_REVERSE_SAFE ,
-.Nm TAILQ_HEAD ,
-.Nm TAILQ_HEAD_INITIALIZER ,
-.Nm TAILQ_INIT ,
-.Nm TAILQ_INSERT_AFTER ,
-.Nm TAILQ_INSERT_BEFORE ,
-.Nm TAILQ_INSERT_HEAD ,
-.Nm TAILQ_INSERT_TAIL ,
-.Nm TAILQ_LAST ,
-.Nm TAILQ_NEXT ,
-.Nm TAILQ_PREV ,
-.Nm TAILQ_REMOVE ,
-.Nm TAILQ_SWAP
-.Nd implementations of singly-linked lists, singly-linked tail queues,
-lists and tail queues
-.Sh SYNOPSIS
-.In sys/queue.h
-.\"
-.Fn SLIST_EMPTY "SLIST_HEAD *head"
-.Fn SLIST_ENTRY "TYPE"
-.Fn SLIST_FIRST "SLIST_HEAD *head"
-.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
-.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
-.Fn SLIST_HEAD "HEADNAME" "TYPE"
-.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
-.Fn SLIST_INIT "SLIST_HEAD *head"
-.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
-.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
-.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
-.Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME"
-.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
-.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
-.Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "SLIST_ENTRY NAME"
-.\"
-.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
-.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
-.Fn STAILQ_ENTRY "TYPE"
-.Fn STAILQ_FIRST "STAILQ_HEAD *head"
-.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
-.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
-.Fn STAILQ_HEAD "HEADNAME" "TYPE"
-.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
-.Fn STAILQ_INIT "STAILQ_HEAD *head"
-.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
-.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
-.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
-.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE" "STAILQ_ENTRY NAME"
-.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
-.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
-.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
-.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
-.Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "STAILQ_ENTRY NAME"
-.\"
-.Fn LIST_EMPTY "LIST_HEAD *head"
-.Fn LIST_ENTRY "TYPE"
-.Fn LIST_FIRST "LIST_HEAD *head"
-.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
-.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
-.Fn LIST_HEAD "HEADNAME" "TYPE"
-.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
-.Fn LIST_INIT "LIST_HEAD *head"
-.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
-.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
-.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
-.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
-.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
-.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
-.\"
-.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
-.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
-.Fn TAILQ_ENTRY "TYPE"
-.Fn TAILQ_FIRST "TAILQ_HEAD *head"
-.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
-.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
-.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
-.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
-.Fn TAILQ_HEAD "HEADNAME" "TYPE"
-.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
-.Fn TAILQ_INIT "TAILQ_HEAD *head"
-.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
-.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
-.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
-.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
-.\"
-.Sh DESCRIPTION
-These macros define and operate on four types of data structures:
-singly-linked lists, singly-linked tail queues, lists, and tail queues.
-All four structures support the following functionality:
-.Bl -enum -compact -offset indent
-.It
-Insertion of a new entry at the head of the list.
-.It
-Insertion of a new entry after any element in the list.
-.It
-O(1) removal of an entry from the head of the list.
-.It
-Forward traversal through the list.
-.It
-Swawpping the contents of two lists.
-.El
-.Pp
-Singly-linked lists are the simplest of the four data structures
-and support only the above functionality.
-Singly-linked lists are ideal for applications with large datasets
-and few or no removals,
-or for implementing a LIFO queue.
-Singly-linked lists add the following functionality:
-.Bl -enum -compact -offset indent
-.It
-O(n) removal of any entry in the list.
-.El
-.Pp
-Singly-linked tail queues add the following functionality:
-.Bl -enum -compact -offset indent
-.It
-Entries can be added at the end of a list.
-.It
-O(n) removal of any entry in the list.
-.It
-They may be concatenated.
-.El
-However:
-.Bl -enum -compact -offset indent
-.It
-All list insertions must specify the head of the list.
-.It
-Each head entry requires two pointers rather than one.
-.It
-Code size is about 15% greater and operations run about 20% slower
-than singly-linked lists.
-.El
-.Pp
-Singly-linked tailqs are ideal for applications with large datasets and
-few or no removals,
-or for implementing a FIFO queue.
-.Pp
-All doubly linked types of data structures (lists and tail queues)
-additionally allow:
-.Bl -enum -compact -offset indent
-.It
-Insertion of a new entry before any element in the list.
-.It
-O(1) removal of any entry in the list.
-.El
-However:
-.Bl -enum -compact -offset indent
-.It
-Each element requires two pointers rather than one.
-.It
-Code size and execution time of operations (except for removal) is about
-twice that of the singly-linked data-structures.
-.El
-.Pp
-Linked lists are the simplest of the doubly linked data structures and support
-only the above functionality over singly-linked lists.
-.Pp
-Tail queues add the following functionality:
-.Bl -enum -compact -offset indent
-.It
-Entries can be added at the end of a list.
-.It
-They may be traversed backwards, from tail to head.
-.It
-They may be concatenated.
-.El
-However:
-.Bl -enum -compact -offset indent
-.It
-All list insertions and removals must specify the head of the list.
-.It
-Each head entry requires two pointers rather than one.
-.It
-Code size is about 15% greater and operations run about 20% slower
-than singly-linked lists.
-.El
-.Pp
-In the macro definitions,
-.Fa TYPE
-is the name of a user defined structure,
-that must contain a field of type
-.Li SLIST_ENTRY ,
-.Li STAILQ_ENTRY ,
-.Li LIST_ENTRY ,
-or
-.Li TAILQ_ENTRY ,
-named
-.Fa NAME .
-The argument
-.Fa HEADNAME
-is the name of a user defined structure that must be declared
-using the macros
-.Li SLIST_HEAD ,
-.Li STAILQ_HEAD ,
-.Li LIST_HEAD ,
-or
-.Li TAILQ_HEAD .
-See the examples below for further explanation of how these
-macros are used.
-.Sh SINGLY-LINKED LISTS
-A singly-linked list is headed by a structure defined by the
-.Nm SLIST_HEAD
-macro.
-This structure contains a single pointer to the first element
-on the list.
-The elements are singly linked for minimum space and pointer manipulation
-overhead at the expense of O(n) removal for arbitrary elements.
-New elements can be added to the list after an existing element or
-at the head of the list.
-An
-.Fa SLIST_HEAD
-structure is declared as follows:
-.Bd -literal -offset indent
-SLIST_HEAD(HEADNAME, TYPE) head;
-.Ed
-.Pp
-where
-.Fa HEADNAME
-is the name of the structure to be defined, and
-.Fa TYPE
-is the type of the elements to be linked into the list.
-A pointer to the head of the list can later be declared as:
-.Bd -literal -offset indent
-struct HEADNAME *headp;
-.Ed
-.Pp
-(The names
-.Li head
-and
-.Li headp
-are user selectable.)
-.Pp
-The macro
-.Nm SLIST_HEAD_INITIALIZER
-evaluates to an initializer for the list
-.Fa head .
-.Pp
-The macro
-.Nm SLIST_EMPTY
-evaluates to true if there are no elements in the list.
-.Pp
-The macro
-.Nm SLIST_ENTRY
-declares a structure that connects the elements in
-the list.
-.Pp
-The macro
-.Nm SLIST_FIRST
-returns the first element in the list or NULL if the list is empty.
-.Pp
-The macro
-.Nm SLIST_FOREACH
-traverses the list referenced by
-.Fa head
-in the forward direction, assigning each element in
-turn to
-.Fa var .
-.Pp
-The macro
-.Nm SLIST_FOREACH_SAFE
-traverses the list referenced by
-.Fa head
-in the forward direction, assigning each element in
-turn to
-.Fa var .
-However, unlike
-.Fn SLIST_FOREACH
-here it is permitted to both remove
-.Fa var
-as well as free it from within the loop safely without interfering with the
-traversal.
-.Pp
-The macro
-.Nm SLIST_INIT
-initializes the list referenced by
-.Fa head .
-.Pp
-The macro
-.Nm SLIST_INSERT_HEAD
-inserts the new element
-.Fa elm
-at the head of the list.
-.Pp
-The macro
-.Nm SLIST_INSERT_AFTER
-inserts the new element
-.Fa elm
-after the element
-.Fa listelm .
-.Pp
-The macro
-.Nm SLIST_NEXT
-returns the next element in the list.
-.Pp
-The macro
-.Nm SLIST_REMOVE_AFTER
-removes the element after
-.Fa elm
-from the list. Unlike
-.Fa SLIST_REMOVE ,
-this macro does not traverse the entire list.
-.Pp
-The macro
-.Nm SLIST_REMOVE_HEAD
-removes the element
-.Fa elm
-from the head of the list.
-For optimum efficiency,
-elements being removed from the head of the list should explicitly use
-this macro instead of the generic
-.Fa SLIST_REMOVE
-macro.
-.Pp
-The macro
-.Nm SLIST_REMOVE
-removes the element
-.Fa elm
-from the list.
-.Pp
-The macro
-.Nm SLIST_SWAP
-swaps the contents of
-.Fa head1
-and
-.Fa head2 .
-.Sh SINGLY-LINKED LIST EXAMPLE
-.Bd -literal
-SLIST_HEAD(slisthead, entry) head =
- SLIST_HEAD_INITIALIZER(head);
-struct slisthead *headp; /* Singly-linked List head. */
-struct entry {
- ...
- SLIST_ENTRY(entry) entries; /* Singly-linked List. */
- ...
-} *n1, *n2, *n3, *np;
-
-SLIST_INIT(&head); /* Initialize the list. */
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
-SLIST_INSERT_HEAD(&head, n1, entries);
-
-n2 = malloc(sizeof(struct entry)); /* Insert after. */
-SLIST_INSERT_AFTER(n1, n2, entries);
-
-SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
-free(n2);
-
-n3 = SLIST_FIRST(&head);
-SLIST_REMOVE_HEAD(&head, entries); /* Deletion from the head. */
-free(n3);
- /* Forward traversal. */
-SLIST_FOREACH(np, &head, entries)
- np-> ...
- /* Safe forward traversal. */
-SLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
- np->do_stuff();
- ...
- SLIST_REMOVE(&head, np, entry, entries);
- free(np);
-}
-
-while (!SLIST_EMPTY(&head)) { /* List Deletion. */
- n1 = SLIST_FIRST(&head);
- SLIST_REMOVE_HEAD(&head, entries);
- free(n1);
-}
-.Ed
-.Sh SINGLY-LINKED TAIL QUEUES
-A singly-linked tail queue is headed by a structure defined by the
-.Nm STAILQ_HEAD
-macro.
-This structure contains a pair of pointers,
-one to the first element in the tail queue and the other to
-the last element in the tail queue.
-The elements are singly linked for minimum space and pointer
-manipulation overhead at the expense of O(n) removal for arbitrary
-elements.
-New elements can be added to the tail queue after an existing element,
-at the head of the tail queue, or at the end of the tail queue.
-A
-.Fa STAILQ_HEAD
-structure is declared as follows:
-.Bd -literal -offset indent
-STAILQ_HEAD(HEADNAME, TYPE) head;
-.Ed
-.Pp
-where
-.Li HEADNAME
-is the name of the structure to be defined, and
-.Li TYPE
-is the type of the elements to be linked into the tail queue.
-A pointer to the head of the tail queue can later be declared as:
-.Bd -literal -offset indent
-struct HEADNAME *headp;
-.Ed
-.Pp
-(The names
-.Li head
-and
-.Li headp
-are user selectable.)
-.Pp
-The macro
-.Nm STAILQ_HEAD_INITIALIZER
-evaluates to an initializer for the tail queue
-.Fa head .
-.Pp
-The macro
-.Nm STAILQ_CONCAT
-concatenates the tail queue headed by
-.Fa head2
-onto the end of the one headed by
-.Fa head1
-removing all entries from the former.
-.Pp
-The macro
-.Nm STAILQ_EMPTY
-evaluates to true if there are no items on the tail queue.
-.Pp
-The macro
-.Nm STAILQ_ENTRY
-declares a structure that connects the elements in
-the tail queue.
-.Pp
-The macro
-.Nm STAILQ_FIRST
-returns the first item on the tail queue or NULL if the tail queue
-is empty.
-.Pp
-The macro
-.Nm STAILQ_FOREACH
-traverses the tail queue referenced by
-.Fa head
-in the forward direction, assigning each element
-in turn to
-.Fa var .
-.Pp
-The macro
-.Nm STAILQ_FOREACH_SAFE
-traverses the tail queue referenced by
-.Fa head
-in the forward direction, assigning each element
-in turn to
-.Fa var .
-However, unlike
-.Fn STAILQ_FOREACH
-here it is permitted to both remove
-.Fa var
-as well as free it from within the loop safely without interfering with the
-traversal.
-.Pp
-The macro
-.Nm STAILQ_INIT
-initializes the tail queue referenced by
-.Fa head .
-.Pp
-The macro
-.Nm STAILQ_INSERT_HEAD
-inserts the new element
-.Fa elm
-at the head of the tail queue.
-.Pp
-The macro
-.Nm STAILQ_INSERT_TAIL
-inserts the new element
-.Fa elm
-at the end of the tail queue.
-.Pp
-The macro
-.Nm STAILQ_INSERT_AFTER
-inserts the new element
-.Fa elm
-after the element
-.Fa listelm .
-.Pp
-The macro
-.Nm STAILQ_LAST
-returns the last item on the tail queue.
-If the tail queue is empty the return value is
-.Dv NULL .
-.Pp
-The macro
-.Nm STAILQ_NEXT
-returns the next item on the tail queue, or NULL this item is the last.
-.Pp
-The macro
-.Nm STAILQ_REMOVE_AFTER
-removes the element after
-.Fa elm
-from the tail queue. Unlike
-.Fa STAILQ_REMOVE ,
-this macro does not traverse the entire tail queue.
-.Pp
-The macro
-.Nm STAILQ_REMOVE_HEAD
-removes the element at the head of the tail queue.
-For optimum efficiency,
-elements being removed from the head of the tail queue should
-use this macro explicitly rather than the generic
-.Fa STAILQ_REMOVE
-macro.
-.Pp
-The macro
-.Nm STAILQ_REMOVE
-removes the element
-.Fa elm
-from the tail queue.
-.Pp
-The macro
-.Nm STAILQ_SWAP
-swaps the contents of
-.Fa head1
-and
-.Fa head2 .
-.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
-.Bd -literal
-STAILQ_HEAD(stailhead, entry) head =
- STAILQ_HEAD_INITIALIZER(head);
-struct stailhead *headp; /* Singly-linked tail queue head. */
-struct entry {
- ...
- STAILQ_ENTRY(entry) entries; /* Tail queue. */
- ...
-} *n1, *n2, *n3, *np;
-
-STAILQ_INIT(&head); /* Initialize the queue. */
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
-STAILQ_INSERT_HEAD(&head, n1, entries);
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
-STAILQ_INSERT_TAIL(&head, n1, entries);
-
-n2 = malloc(sizeof(struct entry)); /* Insert after. */
-STAILQ_INSERT_AFTER(&head, n1, n2, entries);
- /* Deletion. */
-STAILQ_REMOVE(&head, n2, entry, entries);
-free(n2);
- /* Deletion from the head. */
-n3 = STAILQ_FIRST(&head);
-STAILQ_REMOVE_HEAD(&head, entries);
-free(n3);
- /* Forward traversal. */
-STAILQ_FOREACH(np, &head, entries)
- np-> ...
- /* Safe forward traversal. */
-STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
- np->do_stuff();
- ...
- STAILQ_REMOVE(&head, np, entry, entries);
- free(np);
-}
- /* TailQ Deletion. */
-while (!STAILQ_EMPTY(&head)) {
- n1 = STAILQ_FIRST(&head);
- STAILQ_REMOVE_HEAD(&head, entries);
- free(n1);
-}
- /* Faster TailQ Deletion. */
-n1 = STAILQ_FIRST(&head);
-while (n1 != NULL) {
- n2 = STAILQ_NEXT(n1, entries);
- free(n1);
- n1 = n2;
-}
-STAILQ_INIT(&head);
-.Ed
-.Sh LISTS
-A list is headed by a structure defined by the
-.Nm LIST_HEAD
-macro.
-This structure contains a single pointer to the first element
-on the list.
-The elements are doubly linked so that an arbitrary element can be
-removed without traversing the list.
-New elements can be added to the list after an existing element,
-before an existing element, or at the head of the list.
-A
-.Fa LIST_HEAD
-structure is declared as follows:
-.Bd -literal -offset indent
-LIST_HEAD(HEADNAME, TYPE) head;
-.Ed
-.Pp
-where
-.Fa HEADNAME
-is the name of the structure to be defined, and
-.Fa TYPE
-is the type of the elements to be linked into the list.
-A pointer to the head of the list can later be declared as:
-.Bd -literal -offset indent
-struct HEADNAME *headp;
-.Ed
-.Pp
-(The names
-.Li head
-and
-.Li headp
-are user selectable.)
-.Pp
-The macro
-.Nm LIST_HEAD_INITIALIZER
-evaluates to an initializer for the list
-.Fa head .
-.Pp
-The macro
-.Nm LIST_EMPTY
-evaluates to true if there are no elements in the list.
-.Pp
-The macro
-.Nm LIST_ENTRY
-declares a structure that connects the elements in
-the list.
-.Pp
-The macro
-.Nm LIST_FIRST
-returns the first element in the list or NULL if the list
-is empty.
-.Pp
-The macro
-.Nm LIST_FOREACH
-traverses the list referenced by
-.Fa head
-in the forward direction, assigning each element in turn to
-.Fa var .
-.Pp
-The macro
-.Nm LIST_FOREACH_SAFE
-traverses the list referenced by
-.Fa head
-in the forward direction, assigning each element in turn to
-.Fa var .
-However, unlike
-.Fn LIST_FOREACH
-here it is permitted to both remove
-.Fa var
-as well as free it from within the loop safely without interfering with the
-traversal.
-.Pp
-The macro
-.Nm LIST_INIT
-initializes the list referenced by
-.Fa head .
-.Pp
-The macro
-.Nm LIST_INSERT_HEAD
-inserts the new element
-.Fa elm
-at the head of the list.
-.Pp
-The macro
-.Nm LIST_INSERT_AFTER
-inserts the new element
-.Fa elm
-after the element
-.Fa listelm .
-.Pp
-The macro
-.Nm LIST_INSERT_BEFORE
-inserts the new element
-.Fa elm
-before the element
-.Fa listelm .
-.Pp
-The macro
-.Nm LIST_NEXT
-returns the next element in the list, or NULL if this is the last.
-.Pp
-The macro
-.Nm LIST_REMOVE
-removes the element
-.Fa elm
-from the list.
-.Pp
-The macro
-.Nm LIST_SWAP
-swaps the contents of
-.Fa head1
-and
-.Fa head2 .
-.Sh LIST EXAMPLE
-.Bd -literal
-LIST_HEAD(listhead, entry) head =
- LIST_HEAD_INITIALIZER(head);
-struct listhead *headp; /* List head. */
-struct entry {
- ...
- LIST_ENTRY(entry) entries; /* List. */
- ...
-} *n1, *n2, *n3, *np, *np_temp;
-
-LIST_INIT(&head); /* Initialize the list. */
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
-LIST_INSERT_HEAD(&head, n1, entries);
-
-n2 = malloc(sizeof(struct entry)); /* Insert after. */
-LIST_INSERT_AFTER(n1, n2, entries);
-
-n3 = malloc(sizeof(struct entry)); /* Insert before. */
-LIST_INSERT_BEFORE(n2, n3, entries);
-
-LIST_REMOVE(n2, entries); /* Deletion. */
-free(n2);
- /* Forward traversal. */
-LIST_FOREACH(np, &head, entries)
- np-> ...
-
- /* Safe forward traversal. */
-LIST_FOREACH_SAFE(np, &head, entries, np_temp) {
- np->do_stuff();
- ...
- LIST_REMOVE(np, entries);
- free(np);
-}
-
-while (!LIST_EMPTY(&head)) { /* List Deletion. */
- n1 = LIST_FIRST(&head);
- LIST_REMOVE(n1, entries);
- free(n1);
-}
-
-n1 = LIST_FIRST(&head); /* Faster List Deletion. */
-while (n1 != NULL) {
- n2 = LIST_NEXT(n1, entries);
- free(n1);
- n1 = n2;
-}
-LIST_INIT(&head);
-.Ed
-.Sh TAIL QUEUES
-A tail queue is headed by a structure defined by the
-.Nm TAILQ_HEAD
-macro.
-This structure contains a pair of pointers,
-one to the first element in the tail queue and the other to
-the last element in the tail queue.
-The elements are doubly linked so that an arbitrary element can be
-removed without traversing the tail queue.
-New elements can be added to the tail queue after an existing element,
-before an existing element, at the head of the tail queue,
-or at the end of the tail queue.
-A
-.Fa TAILQ_HEAD
-structure is declared as follows:
-.Bd -literal -offset indent
-TAILQ_HEAD(HEADNAME, TYPE) head;
-.Ed
-.Pp
-where
-.Li HEADNAME
-is the name of the structure to be defined, and
-.Li TYPE
-is the type of the elements to be linked into the tail queue.
-A pointer to the head of the tail queue can later be declared as:
-.Bd -literal -offset indent
-struct HEADNAME *headp;
-.Ed
-.Pp
-(The names
-.Li head
-and
-.Li headp
-are user selectable.)
-.Pp
-The macro
-.Nm TAILQ_HEAD_INITIALIZER
-evaluates to an initializer for the tail queue
-.Fa head .
-.Pp
-The macro
-.Nm TAILQ_CONCAT
-concatenates the tail queue headed by
-.Fa head2
-onto the end of the one headed by
-.Fa head1
-removing all entries from the former.
-.Pp
-The macro
-.Nm TAILQ_EMPTY
-evaluates to true if there are no items on the tail queue.
-.Pp
-The macro
-.Nm TAILQ_ENTRY
-declares a structure that connects the elements in
-the tail queue.
-.Pp
-The macro
-.Nm TAILQ_FIRST
-returns the first item on the tail queue or NULL if the tail queue
-is empty.
-.Pp
-The macro
-.Nm TAILQ_FOREACH
-traverses the tail queue referenced by
-.Fa head
-in the forward direction, assigning each element in turn to
-.Fa var .
-.Fa var
-is set to
-.Dv NULL
-if the loop completes normally, or if there were no elements.
-.Pp
-The macro
-.Nm TAILQ_FOREACH_REVERSE
-traverses the tail queue referenced by
-.Fa head
-in the reverse direction, assigning each element in turn to
-.Fa var .
-.Pp
-The macros
-.Nm TAILQ_FOREACH_SAFE
-and
-.Nm TAILQ_FOREACH_REVERSE_SAFE
-traverse the list referenced by
-.Fa head
-in the forward or reverse direction respectively,
-assigning each element in turn to
-.Fa var .
-However, unlike their unsafe counterparts,
-.Nm TAILQ_FOREACH
-and
-.Nm TAILQ_FOREACH_REVERSE
-permit to both remove
-.Fa var
-as well as free it from within the loop safely without interfering with the
-traversal.
-.Pp
-The macro
-.Nm TAILQ_INIT
-initializes the tail queue referenced by
-.Fa head .
-.Pp
-The macro
-.Nm TAILQ_INSERT_HEAD
-inserts the new element
-.Fa elm
-at the head of the tail queue.
-.Pp
-The macro
-.Nm TAILQ_INSERT_TAIL
-inserts the new element
-.Fa elm
-at the end of the tail queue.
-.Pp
-The macro
-.Nm TAILQ_INSERT_AFTER
-inserts the new element
-.Fa elm
-after the element
-.Fa listelm .
-.Pp
-The macro
-.Nm TAILQ_INSERT_BEFORE
-inserts the new element
-.Fa elm
-before the element
-.Fa listelm .
-.Pp
-The macro
-.Nm TAILQ_LAST
-returns the last item on the tail queue.
-If the tail queue is empty the return value is
-.Dv NULL .
-.Pp
-The macro
-.Nm TAILQ_NEXT
-returns the next item on the tail queue, or NULL if this item is the last.
-.Pp
-The macro
-.Nm TAILQ_PREV
-returns the previous item on the tail queue, or NULL if this item
-is the first.
-.Pp
-The macro
-.Nm TAILQ_REMOVE
-removes the element
-.Fa elm
-from the tail queue.
-.Pp
-The macro
-.Nm TAILQ_SWAP
-swaps the contents of
-.Fa head1
-and
-.Fa head2 .
-.Sh TAIL QUEUE EXAMPLE
-.Bd -literal
-TAILQ_HEAD(tailhead, entry) head =
- TAILQ_HEAD_INITIALIZER(head);
-struct tailhead *headp; /* Tail queue head. */
-struct entry {
- ...
- TAILQ_ENTRY(entry) entries; /* Tail queue. */
- ...
-} *n1, *n2, *n3, *np;
-
-TAILQ_INIT(&head); /* Initialize the queue. */
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
-TAILQ_INSERT_HEAD(&head, n1, entries);
-
-n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
-TAILQ_INSERT_TAIL(&head, n1, entries);
-
-n2 = malloc(sizeof(struct entry)); /* Insert after. */
-TAILQ_INSERT_AFTER(&head, n1, n2, entries);
-
-n3 = malloc(sizeof(struct entry)); /* Insert before. */
-TAILQ_INSERT_BEFORE(n2, n3, entries);
-
-TAILQ_REMOVE(&head, n2, entries); /* Deletion. */
-free(n2);
- /* Forward traversal. */
-TAILQ_FOREACH(np, &head, entries)
- np-> ...
- /* Safe forward traversal. */
-TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
- np->do_stuff();
- ...
- TAILQ_REMOVE(&head, np, entries);
- free(np);
-}
- /* Reverse traversal. */
-TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
- np-> ...
- /* TailQ Deletion. */
-while (!TAILQ_EMPTY(&head)) {
- n1 = TAILQ_FIRST(&head);
- TAILQ_REMOVE(&head, n1, entries);
- free(n1);
-}
- /* Faster TailQ Deletion. */
-n1 = TAILQ_FIRST(&head);
-while (n1 != NULL) {
- n2 = TAILQ_NEXT(n1, entries);
- free(n1);
- n1 = n2;
-}
-TAILQ_INIT(&head);
-.Ed
-.Sh SEE ALSO
-.Xr tree 3
-.Sh HISTORY
-The
-.Nm queue
-functions first appeared in
-.Bx 4.4 .
+++ /dev/null
-#!/usr/bin/perl -p
-#
-# This script is part of the Xen build system. It has a very
-# permissive licence to avoid complicating the licence of the
-# generated header file and to allow this seddery to be reused by
-# other projects.
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this individual file (the "Software"), to deal
-# in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute,
-# sublicense, and/or sell copies of the Software, and to permit
-# persons to whom the Software is furnished to do so, subject to the
-# following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (C) 2011 Citrix Ltd
-
-our $namespace, $ucnamespace;
-
-BEGIN {
- die unless @ARGV;
- $namespace = pop @ARGV;
- $namespace =~ s/^--prefix=// or die;
- $ucnamespace = uc $namespace;
-
- print <<END or die $!;
-/*
- * DO NOT EDIT THIS FILE
- *
- * Generated automatically by bsd-sys-queue-h-seddery to
- * - introduce ${ucnamespace}_ and ${namespace}_ namespace prefixes
- * - turn "struct type" into "type" so that type arguments
- * to the macros are type names not struct tags
- * - remove the reference to sys/cdefs.h, which is not needed
- *
- * The purpose of this seddery is to allow the resulting file to be
- * freely included by software which might also want to include other
- * list macros; to make it usable when struct tags are not being used
- * or not known; to make it more portable.
- */
-END
-}
-
-s/\b( _SYS_QUEUE |
- SLIST | LIST | STAILQ | TAILQ | QUEUE
- )/${ucnamespace}_$1/xg;
-
-s/\b( TRACEBUF | TRASHIT |
- QMD_
- )/${ucnamespace}__$1/xg;
-
-s/\b(
- qm_
- )/${namespace}__$1/xg;
-
-s/\b struct \s+ type \b/type/xg;
-
-s,^\#include.*sys/cdefs.*,/* $& */,xg;
-
-s/\b( NULL )/0/xg;
+++ /dev/null
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- * $FreeBSD$
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-#include <sys/cdefs.h>
-
-/*
- * This file defines four types of data structures: singly-linked lists,
- * singly-linked tail queues, lists and tail queues.
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction. Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A singly-linked tail queue is headed by a pair of pointers, one to the
- * head of the list and the other to the tail of the list. The elements are
- * singly linked for minimum space and pointer manipulation overhead at the
- * expense of O(n) removal for arbitrary elements. New elements can be added
- * to the list after an existing element, at the head of the list, or at the
- * end of the list. Elements being removed from the head of the tail queue
- * should use the explicit macro for this purpose for optimum efficiency.
- * A singly-linked tail queue may only be traversed in the forward direction.
- * Singly-linked tail queues are ideal for applications with large datasets
- * and few or no removals or for implementing a FIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *
- *
- * SLIST LIST STAILQ TAILQ
- * _HEAD + + + +
- * _HEAD_INITIALIZER + + + +
- * _ENTRY + + + +
- * _INIT + + + +
- * _EMPTY + + + +
- * _FIRST + + + +
- * _NEXT + + + +
- * _PREV - - - +
- * _LAST - - + +
- * _FOREACH + + + +
- * _FOREACH_SAFE + + + +
- * _FOREACH_REVERSE - - - +
- * _FOREACH_REVERSE_SAFE - - - +
- * _INSERT_HEAD + + + +
- * _INSERT_BEFORE - + - +
- * _INSERT_AFTER + + + +
- * _INSERT_TAIL - - + +
- * _CONCAT - - + +
- * _REMOVE_AFTER + - + -
- * _REMOVE_HEAD + - + -
- * _REMOVE + + + +
- * _SWAP + + + +
- *
- */
-#ifdef QUEUE_MACRO_DEBUG
-/* Store the last 2 places the queue element or head was altered */
-struct qm_trace {
- char * lastfile;
- int lastline;
- char * prevfile;
- int prevline;
-};
-
-#define TRACEBUF struct qm_trace trace;
-#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
-#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
-
-#define QMD_TRACE_HEAD(head) do { \
- (head)->trace.prevline = (head)->trace.lastline; \
- (head)->trace.prevfile = (head)->trace.lastfile; \
- (head)->trace.lastline = __LINE__; \
- (head)->trace.lastfile = __FILE__; \
-} while (0)
-
-#define QMD_TRACE_ELEM(elem) do { \
- (elem)->trace.prevline = (elem)->trace.lastline; \
- (elem)->trace.prevfile = (elem)->trace.lastfile; \
- (elem)->trace.lastline = __LINE__; \
- (elem)->trace.lastfile = __FILE__; \
-} while (0)
-
-#else
-#define QMD_TRACE_ELEM(elem)
-#define QMD_TRACE_HEAD(head)
-#define QMD_SAVELINK(name, link)
-#define TRACEBUF
-#define TRASHIT(x)
-#endif /* QUEUE_MACRO_DEBUG */
-
-/*
- * Singly-linked List declarations.
- */
-#define SLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define SLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define SLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
-
-#define SLIST_FIRST(head) ((head)->slh_first)
-
-#define SLIST_FOREACH(var, head, field) \
- for ((var) = SLIST_FIRST((head)); \
- (var); \
- (var) = SLIST_NEXT((var), field))
-
-#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SLIST_FIRST((head)); \
- (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
- for ((varp) = &SLIST_FIRST((head)); \
- ((var) = *(varp)) != NULL; \
- (varp) = &SLIST_NEXT((var), field))
-
-#define SLIST_INIT(head) do { \
- SLIST_FIRST((head)) = NULL; \
-} while (0)
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
- SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
- SLIST_NEXT((slistelm), field) = (elm); \
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
- SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
- SLIST_FIRST((head)) = (elm); \
-} while (0)
-
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_REMOVE(head, elm, type, field) do { \
- QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
- if (SLIST_FIRST((head)) == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
- } \
- else { \
- struct type *curelm = SLIST_FIRST((head)); \
- while (SLIST_NEXT(curelm, field) != (elm)) \
- curelm = SLIST_NEXT(curelm, field); \
- SLIST_REMOVE_AFTER(curelm, field); \
- } \
- TRASHIT(*oldnext); \
-} while (0)
-
-#define SLIST_REMOVE_AFTER(elm, field) do { \
- SLIST_NEXT(elm, field) = \
- SLIST_NEXT(SLIST_NEXT(elm, field), field); \
-} while (0)
-
-#define SLIST_REMOVE_HEAD(head, field) do { \
- SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
-} while (0)
-
-#define SLIST_SWAP(head1, head2, type) do { \
- struct type *swap_first = SLIST_FIRST(head1); \
- SLIST_FIRST(head1) = SLIST_FIRST(head2); \
- SLIST_FIRST(head2) = swap_first; \
-} while (0)
-
-/*
- * Singly-linked Tail queue declarations.
- */
-#define STAILQ_HEAD(name, type) \
-struct name { \
- struct type *stqh_first;/* first element */ \
- struct type **stqh_last;/* addr of last next element */ \
-}
-
-#define STAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).stqh_first }
-
-#define STAILQ_ENTRY(type) \
-struct { \
- struct type *stqe_next; /* next element */ \
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define STAILQ_CONCAT(head1, head2) do { \
- if (!STAILQ_EMPTY((head2))) { \
- *(head1)->stqh_last = (head2)->stqh_first; \
- (head1)->stqh_last = (head2)->stqh_last; \
- STAILQ_INIT((head2)); \
- } \
-} while (0)
-
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
-
-#define STAILQ_FIRST(head) ((head)->stqh_first)
-
-#define STAILQ_FOREACH(var, head, field) \
- for((var) = STAILQ_FIRST((head)); \
- (var); \
- (var) = STAILQ_NEXT((var), field))
-
-
-#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = STAILQ_FIRST((head)); \
- (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#define STAILQ_INIT(head) do { \
- STAILQ_FIRST((head)) = NULL; \
- (head)->stqh_last = &STAILQ_FIRST((head)); \
-} while (0)
-
-#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
- if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
- STAILQ_NEXT((tqelm), field) = (elm); \
-} while (0)
-
-#define STAILQ_INSERT_HEAD(head, elm, field) do { \
- if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
- STAILQ_FIRST((head)) = (elm); \
-} while (0)
-
-#define STAILQ_INSERT_TAIL(head, elm, field) do { \
- STAILQ_NEXT((elm), field) = NULL; \
- *(head)->stqh_last = (elm); \
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
-} while (0)
-
-#define STAILQ_LAST(head, type, field) \
- (STAILQ_EMPTY((head)) ? \
- NULL : \
- ((struct type *)(void *) \
- ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
-
-#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
-
-#define STAILQ_REMOVE(head, elm, type, field) do { \
- QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
- if (STAILQ_FIRST((head)) == (elm)) { \
- STAILQ_REMOVE_HEAD((head), field); \
- } \
- else { \
- struct type *curelm = STAILQ_FIRST((head)); \
- while (STAILQ_NEXT(curelm, field) != (elm)) \
- curelm = STAILQ_NEXT(curelm, field); \
- STAILQ_REMOVE_AFTER(head, curelm, field); \
- } \
- TRASHIT(*oldnext); \
-} while (0)
-
-#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
- if ((STAILQ_NEXT(elm, field) = \
- STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
-} while (0)
-
-#define STAILQ_REMOVE_HEAD(head, field) do { \
- if ((STAILQ_FIRST((head)) = \
- STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
- (head)->stqh_last = &STAILQ_FIRST((head)); \
-} while (0)
-
-#define STAILQ_SWAP(head1, head2, type) do { \
- struct type *swap_first = STAILQ_FIRST(head1); \
- struct type **swap_last = (head1)->stqh_last; \
- STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
- (head1)->stqh_last = (head2)->stqh_last; \
- STAILQ_FIRST(head2) = swap_first; \
- (head2)->stqh_last = swap_last; \
- if (STAILQ_EMPTY(head1)) \
- (head1)->stqh_last = &STAILQ_FIRST(head1); \
- if (STAILQ_EMPTY(head2)) \
- (head2)->stqh_last = &STAILQ_FIRST(head2); \
-} while (0)
-
-
-/*
- * List declarations.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-
-#if (defined(_KERNEL) && defined(INVARIANTS))
-#define QMD_LIST_CHECK_HEAD(head, field) do { \
- if (LIST_FIRST((head)) != NULL && \
- LIST_FIRST((head))->field.le_prev != \
- &LIST_FIRST((head))) \
- panic("Bad list head %p first->prev != head", (head)); \
-} while (0)
-
-#define QMD_LIST_CHECK_NEXT(elm, field) do { \
- if (LIST_NEXT((elm), field) != NULL && \
- LIST_NEXT((elm), field)->field.le_prev != \
- &((elm)->field.le_next)) \
- panic("Bad link elm %p next->prev != elm", (elm)); \
-} while (0)
-
-#define QMD_LIST_CHECK_PREV(elm, field) do { \
- if (*(elm)->field.le_prev != (elm)) \
- panic("Bad link elm %p prev->next != elm", (elm)); \
-} while (0)
-#else
-#define QMD_LIST_CHECK_HEAD(head, field)
-#define QMD_LIST_CHECK_NEXT(elm, field)
-#define QMD_LIST_CHECK_PREV(elm, field)
-#endif /* (_KERNEL && INVARIANTS) */
-
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-
-#define LIST_FIRST(head) ((head)->lh_first)
-
-#define LIST_FOREACH(var, head, field) \
- for ((var) = LIST_FIRST((head)); \
- (var); \
- (var) = LIST_NEXT((var), field))
-
-#define LIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = LIST_FIRST((head)); \
- (var) && ((tvar) = LIST_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#define LIST_INIT(head) do { \
- LIST_FIRST((head)) = NULL; \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- QMD_LIST_CHECK_NEXT(listelm, field); \
- if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
- LIST_NEXT((listelm), field)->field.le_prev = \
- &LIST_NEXT((elm), field); \
- LIST_NEXT((listelm), field) = (elm); \
- (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- QMD_LIST_CHECK_PREV(listelm, field); \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- LIST_NEXT((elm), field) = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- QMD_LIST_CHECK_HEAD((head), field); \
- if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
- LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
- LIST_FIRST((head)) = (elm); \
- (elm)->field.le_prev = &LIST_FIRST((head)); \
-} while (0)
-
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_REMOVE(elm, field) do { \
- QMD_SAVELINK(oldnext, (elm)->field.le_next); \
- QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
- QMD_LIST_CHECK_NEXT(elm, field); \
- QMD_LIST_CHECK_PREV(elm, field); \
- if (LIST_NEXT((elm), field) != NULL) \
- LIST_NEXT((elm), field)->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = LIST_NEXT((elm), field); \
- TRASHIT(*oldnext); \
- TRASHIT(*oldprev); \
-} while (0)
-
-#define LIST_SWAP(head1, head2, type, field) do { \
- struct type *swap_tmp = LIST_FIRST((head1)); \
- LIST_FIRST((head1)) = LIST_FIRST((head2)); \
- LIST_FIRST((head2)) = swap_tmp; \
- if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
- swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
- if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
- swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
-} while (0)
-
-/*
- * Tail queue declarations.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
- TRACEBUF \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
- TRACEBUF \
-}
-
-/*
- * Tail queue functions.
- */
-#if (defined(_KERNEL) && defined(INVARIANTS))
-#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
- if (!TAILQ_EMPTY(head) && \
- TAILQ_FIRST((head))->field.tqe_prev != \
- &TAILQ_FIRST((head))) \
- panic("Bad tailq head %p first->prev != head", (head)); \
-} while (0)
-
-#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
- if (*(head)->tqh_last != NULL) \
- panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
-} while (0)
-
-#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
- if (TAILQ_NEXT((elm), field) != NULL && \
- TAILQ_NEXT((elm), field)->field.tqe_prev != \
- &((elm)->field.tqe_next)) \
- panic("Bad link elm %p next->prev != elm", (elm)); \
-} while (0)
-
-#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
- if (*(elm)->field.tqe_prev != (elm)) \
- panic("Bad link elm %p prev->next != elm", (elm)); \
-} while (0)
-#else
-#define QMD_TAILQ_CHECK_HEAD(head, field)
-#define QMD_TAILQ_CHECK_TAIL(head, headname)
-#define QMD_TAILQ_CHECK_NEXT(elm, field)
-#define QMD_TAILQ_CHECK_PREV(elm, field)
-#endif /* (_KERNEL && INVARIANTS) */
-
-#define TAILQ_CONCAT(head1, head2, field) do { \
- if (!TAILQ_EMPTY(head2)) { \
- *(head1)->tqh_last = (head2)->tqh_first; \
- (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
- (head1)->tqh_last = (head2)->tqh_last; \
- TAILQ_INIT((head2)); \
- QMD_TRACE_HEAD(head1); \
- QMD_TRACE_HEAD(head2); \
- } \
-} while (0)
-
-#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-
-#define TAILQ_FOREACH(var, head, field) \
- for ((var) = TAILQ_FIRST((head)); \
- (var); \
- (var) = TAILQ_NEXT((var), field))
-
-#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = TAILQ_FIRST((head)); \
- (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for ((var) = TAILQ_LAST((head), headname); \
- (var); \
- (var) = TAILQ_PREV((var), headname, field))
-
-#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
- for ((var) = TAILQ_LAST((head), headname); \
- (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
- (var) = (tvar))
-
-#define TAILQ_INIT(head) do { \
- TAILQ_FIRST((head)) = NULL; \
- (head)->tqh_last = &TAILQ_FIRST((head)); \
- QMD_TRACE_HEAD(head); \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- QMD_TAILQ_CHECK_NEXT(listelm, field); \
- if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
- TAILQ_NEXT((elm), field)->field.tqe_prev = \
- &TAILQ_NEXT((elm), field); \
- else { \
- (head)->tqh_last = &TAILQ_NEXT((elm), field); \
- QMD_TRACE_HEAD(head); \
- } \
- TAILQ_NEXT((listelm), field) = (elm); \
- (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
- QMD_TRACE_ELEM(&(elm)->field); \
- QMD_TRACE_ELEM(&listelm->field); \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- QMD_TAILQ_CHECK_PREV(listelm, field); \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- TAILQ_NEXT((elm), field) = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
- QMD_TRACE_ELEM(&(elm)->field); \
- QMD_TRACE_ELEM(&listelm->field); \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- QMD_TAILQ_CHECK_HEAD(head, field); \
- if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
- TAILQ_FIRST((head))->field.tqe_prev = \
- &TAILQ_NEXT((elm), field); \
- else \
- (head)->tqh_last = &TAILQ_NEXT((elm), field); \
- TAILQ_FIRST((head)) = (elm); \
- (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
- QMD_TRACE_HEAD(head); \
- QMD_TRACE_ELEM(&(elm)->field); \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- QMD_TAILQ_CHECK_TAIL(head, field); \
- TAILQ_NEXT((elm), field) = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &TAILQ_NEXT((elm), field); \
- QMD_TRACE_HEAD(head); \
- QMD_TRACE_ELEM(&(elm)->field); \
-} while (0)
-
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
- QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
- QMD_TAILQ_CHECK_NEXT(elm, field); \
- QMD_TAILQ_CHECK_PREV(elm, field); \
- if ((TAILQ_NEXT((elm), field)) != NULL) \
- TAILQ_NEXT((elm), field)->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else { \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- QMD_TRACE_HEAD(head); \
- } \
- *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
- TRASHIT(*oldnext); \
- TRASHIT(*oldprev); \
- QMD_TRACE_ELEM(&(elm)->field); \
-} while (0)
-
-#define TAILQ_SWAP(head1, head2, type, field) do { \
- struct type *swap_first = (head1)->tqh_first; \
- struct type **swap_last = (head1)->tqh_last; \
- (head1)->tqh_first = (head2)->tqh_first; \
- (head1)->tqh_last = (head2)->tqh_last; \
- (head2)->tqh_first = swap_first; \
- (head2)->tqh_last = swap_last; \
- if ((swap_first = (head1)->tqh_first) != NULL) \
- swap_first->field.tqe_prev = &(head1)->tqh_first; \
- else \
- (head1)->tqh_last = &(head1)->tqh_first; \
- if ((swap_first = (head2)->tqh_first) != NULL) \
- swap_first->field.tqe_prev = &(head2)->tqh_first; \
- else \
- (head2)->tqh_last = &(head2)->tqh_first; \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- *
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * Copyright (c) 2005, Keir A Fraser
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _MM_H_
-#define _MM_H_
-
-#if defined(__i386__)
-#include <xen/arch-x86_32.h>
-#elif defined(__x86_64__)
-#include <xen/arch-x86_64.h>
-#elif defined(__arm__) || defined(__aarch64__)
-#include <xen/arch-arm.h>
-#else
-#error "Unsupported architecture"
-#endif
-#include <xen/xen.h>
-
-#include <mini-os/arch_limits.h>
-#include <mini-os/arch_mm.h>
-
-#define STACK_SIZE_PAGE_ORDER __STACK_SIZE_PAGE_ORDER
-#define STACK_SIZE __STACK_SIZE
-
-
-void init_mm(void);
-unsigned long alloc_pages(int order);
-#define alloc_page() alloc_pages(0)
-void free_pages(void *pointer, int order);
-#define free_page(p) free_pages(p, 0)
-
-static __inline__ int get_order(unsigned long size)
-{
- int order;
- size = (size-1) >> PAGE_SHIFT;
- for ( order = 0; size; order++ )
- size >>= 1;
- return order;
-}
-
-void arch_init_demand_mapping_area(unsigned long max_pfn);
-void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
-void arch_init_p2m(unsigned long max_pfn_p);
-
-unsigned long allocate_ondemand(unsigned long n, unsigned long alignment);
-/* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */
-void *map_frames_ex(const unsigned long *f, unsigned long n, unsigned long stride,
- unsigned long increment, unsigned long alignment, domid_t id,
- int *err, unsigned long prot);
-void do_map_frames(unsigned long addr,
- const unsigned long *f, unsigned long n, unsigned long stride,
- unsigned long increment, domid_t id, int *err, unsigned long prot);
-int unmap_frames(unsigned long va, unsigned long num_frames);
-unsigned long alloc_contig_pages(int order, unsigned int addr_bits);
-#ifdef HAVE_LIBC
-extern unsigned long heap, brk, heap_mapped, heap_end;
-#endif
-
-int free_physical_pages(xen_pfn_t *mfns, int n);
-void fini_mm(void);
-
-#endif /* _MM_H_ */
+++ /dev/null
-#include <mini-os/wait.h>
-#ifdef HAVE_LWIP
-#include <lwip/netif.h>
-#endif
-struct netfront_dev;
-struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned char *data, int len), unsigned char rawmac[6], char **ip);
-void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
-void shutdown_netfront(struct netfront_dev *dev);
-#ifdef HAVE_LIBC
-int netfront_tap_open(char *nodename);
-ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len);
-#endif
-
-extern struct wait_queue_head netfront_queue;
-
-#ifdef HAVE_LWIP
-/* Call this to bring up the netfront interface and the lwIP stack.
- * N.B. _must_ be called from a thread; it's not safe to call this from
- * app_main(). */
-void start_networking(void);
-void stop_networking(void);
-
-void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw);
-#endif
+++ /dev/null
-#include <mini-os/types.h>
-#include <xen/io/pciif.h>
-struct pcifront_dev;
-void pcifront_watches(void *opaque);
-struct pcifront_dev *init_pcifront(char *nodename);
-void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op);
-void pcifront_scan(struct pcifront_dev *dev, void (*fun)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun));
-int pcifront_conf_read(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- unsigned int off, unsigned int size, unsigned int *val);
-int pcifront_conf_write(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- unsigned int off, unsigned int size, unsigned int val);
-int pcifront_enable_msi(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun);
-int pcifront_disable_msi(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun);
-int pcifront_enable_msix(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- struct xen_msix_entry *entries, int n);
-int pcifront_disable_msix(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun);
-void shutdown_pcifront(struct pcifront_dev *dev);
+++ /dev/null
-#ifndef _POSIX_ARPA_INET_H_
-#define _POSIX_ARPA_INET_H_
-
-#include <lwip/inet.h>
-
-#endif /* _POSIX_ARPA_INET_H_ */
-
+++ /dev/null
-#ifndef _POSIX_DIRENT_H
-#define _POSIX_DIRENT_H
-
-#include <stdint.h>
-
-struct dirent {
- char *d_name;
-};
-
-typedef struct {
- struct dirent dirent;
- char *name;
- int32_t offset;
- char **entries;
- int32_t curentry;
- int32_t nbentries;
- int has_more;
-} DIR;
-
-DIR *opendir(const char *name);
-struct dirent *readdir(DIR *dir);
-int closedir(DIR *dir);
-
-#endif /* _POSIX_DIRENT_H */
+++ /dev/null
-#ifndef _POSIX_ERR_H
-#define _POSIX_ERR_H
-
-#include <stdarg.h>
-
-void err(int eval, const char *fmt, ...);
-void errx(int eval, const char *fmt, ...);
-void warn(const char *fmt, ...);
-void warnx(const char *fmt, ...);
-void verr(int eval, const char *fmt, va_list args);
-void verrx(int eval, const char *fmt, va_list args);
-void vwarn(const char *fmt, va_list args);
-void vwarnx(const char *fmt, va_list args);
-
-#endif /* _POSIX_ERR_H */
+++ /dev/null
-#ifndef _POSIX_FCNTL_H
-#define _POSIX_FCNTL_H
-
-#include_next <fcntl.h>
-
-#define F_ULOCK 0
-#define F_LOCK 1
-#define F_TLOCK 2
-#define F_TEST 3
-
-#endif /* _POSIX_FCNTL_H */
+++ /dev/null
-#ifndef _POSIX_LIMITS_H
-#define _POSIX_LIMITS_H
-
-#include <mini-os/arch_limits.h>
-
-#define CHAR_BIT 8
-
-#define SCHAR_MAX 0x7f
-#define SCHAR_MIN (-SCHAR_MAX-1)
-#define UCHAR_MAX 0xff
-
-#ifdef __CHAR_UNSIGNED__
-# define CHAR_MIN 0
-# define CHAR_MAX UCHAR_MAX
-#else
-# define CHAR_MIN SCHAR_MIN
-# define CHAR_MAX SCHAR_MAX
-#endif
-
-#define INT_MAX 0x7fffffff
-#define INT_MIN (-INT_MAX-1)
-#define UINT_MAX 0xffffffff
-
-#define SHRT_MIN (-0x8000)
-#define SHRT_MAX 0x7fff
-#define USHRT_MAX 0xffff
-
-#if defined(__x86_64__)
-# define LONG_MAX 0x7fffffffffffffffL
-# define ULONG_MAX 0xffffffffffffffffUL
-#else
-# define LONG_MAX 0x7fffffffL
-# define ULONG_MAX 0xffffffffUL
-#endif
-#define LONG_MIN (-LONG_MAX-1L)
-
-#define LLONG_MAX 0x7fffffffffffffffLL
-#define LLONG_MIN (-LLONG_MAX-1LL)
-#define ULLONG_MAX 0xffffffffffffffffULL
-
-#define LONG_LONG_MIN LLONG_MIN
-#define LONG_LONG_MAX LLONG_MAX
-#define ULONG_LONG_MAX ULLONG_MAX
-
-#define PATH_MAX __PAGE_SIZE
-#define PAGE_SIZE __PAGE_SIZE
-
-#endif /* _POSIX_LIMITS_H */
+++ /dev/null
-/*
- * This code is mostly taken from NetBSD net/if.h
- * Changes: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
- *
- ******************************************************************************
- *
- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by William Studenmund and Jason R. Thorpe.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _NET_IF_H_
-#define _NET_IF_H_
-
-/*
- * Length of interface external name, including terminating '\0'.
- * Note: this is the same size as a generic device's external name.
- */
-#define IF_NAMESIZE 16
-
-struct if_nameindex {
- unsigned int if_index; /* 1, 2, ... */
- char *if_name; /* null terminated name: "le0", ... */
-};
-
-unsigned int if_nametoindex(const char *);
-char * if_indextoname(unsigned int, char *);
-struct if_nameindex * if_nameindex(void);
-void if_freenameindex(struct if_nameindex *);
-
-#endif /* !_NET_IF_H_ */
-
+++ /dev/null
-#ifndef _POSIX_NETDB_H_
-#define _POSIX_NETDB_H_
-
-struct hostent {
- char *h_addr;
-};
-#define gethostbyname(buf) NULL
-
-#endif /* _POSIX_NETDB_H_ */
+++ /dev/null
-#ifndef _POSIX_SYS_IN_H_
-#define _POSIX_SYS_IN_H_
-
-#include <fcntl.h>
-#include <lwip/sockets.h>
-
-#endif /* _POSIX_SYS_IN_H_ */
+++ /dev/null
-#ifndef _POSIX_SYS_TCP_H_
-#define _POSIX_SYS_TCP_H_
-
-#include <lwip/tcp.h>
-
-#endif /* _POSIX_SYS_TCP_H_ */
+++ /dev/null
-#include <sys/poll.h>
+++ /dev/null
-#ifndef _POSIX_PTHREAD_H
-#define _POSIX_PTHREAD_H
-
-#include <stdlib.h>
-
-/* Let's be single-threaded for now. */
-
-typedef struct {
- void *ptr;
-} *pthread_key_t;
-static inline int pthread_key_create(pthread_key_t *key, void (*destr_function)(void*))
-{
- *key = malloc(sizeof(**key));
- (*key)->ptr = NULL;
- return 0;
-}
-static inline int pthread_setspecific(pthread_key_t key, const void *pointer)
-{
- key->ptr = (void*) pointer;
- return 0;
-}
-static inline void *pthread_getspecific(pthread_key_t key)
-{
- return key->ptr;
-}
-static inline int pthread_key_delete(pthread_key_t key)
-{
- free(key);
- return 0;
-}
-
-
-
-typedef struct {} pthread_mutexattr_t;
-static inline int pthread_mutexattr_init(pthread_mutexattr_t *mattr) { return 0; }
-#define PTHREAD_MUTEX_NORMAL 0
-#define PTHREAD_MUTEX_RECURSIVE 1
-static inline int pthread_mutexattr_settype(pthread_mutexattr_t *mattr, int kind) { return 0; }
-static inline int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr) { return 0; }
-typedef struct {} pthread_mutex_t;
-#define PTHREAD_MUTEX_INITIALIZER {}
-static inline int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mattr) { return 0; }
-static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return 0; }
-static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; }
-
-
-
-typedef struct {
- int done;
-} pthread_once_t;
-#define PTHREAD_ONCE_INIT { 0 }
-
-static inline int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
-{
- if (!once_control->done) {
- once_control->done = 1;
- init_routine();
- }
- return 0;
-}
-
-#define __thread
-
-#endif /* _POSIX_PTHREAD_H */
+++ /dev/null
-#ifndef _POSIX_SIGNAL_H
-#define _POSIX_SIGNAL_H
-
-#include_next <signal.h>
-
-int sigaction(int signum, const struct sigaction * __restrict,
- struct sigaction * __restrict);
-
-#endif
-
+++ /dev/null
-#ifndef _POSIX_STDLIB_H
-#define _POSIX_STDLIB_H
-
-#include_next <stdlib.h>
-
-#define realpath(p,r) strcpy(r,p)
-
-#endif /* _POSIX_STDLIB_H */
+++ /dev/null
-#ifndef _POSIX_STRINGS_H
-#define _POSIX_STRINGS_H
-
-#include <string.h>
-
-#define bzero(ptr, size) (memset((ptr), '\0', (size)), (void) 0)
-
-int ffs (int i);
-int ffsl (long int li);
-int ffsll (long long int lli);
-
-#endif /* _POSIX_STRINGS_H */
+++ /dev/null
-#ifndef _POSIX_SYS_IOCTL_H
-#define _POSIX_SYS_IOCTL_H
-
-int ioctl(int fd, int request, ...);
-
-#define _IOC_NONE 0
-#define _IOC_WRITE 1
-#define _IOC_READ 2
-
-#define _IOC(rw, class, n, size) \
- (((rw ) << 30) | \
- ((class) << 22) | \
- ((n ) << 14) | \
- ((size ) << 0))
-
-#endif /* _POSIX_SYS_IOCTL_H */
+++ /dev/null
-#ifndef _POSIX_SYS_MMAN_H
-#define _POSIX_SYS_MMAN_H
-
-#define PROT_READ 0x1
-#define PROT_WRITE 0x2
-#define PROT_EXEC 0x4
-
-#define MAP_SHARED 0x01
-#define MAP_PRIVATE 0x02
-#define MAP_ANON 0x20
-
-/* Pages are always resident anyway */
-#define MAP_LOCKED 0x0
-
-#define MAP_FAILED ((void*)0)
-
-void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) asm("mmap64");
-int munmap(void *start, size_t length);
-static inline mlock(const void *addr, size_t len) { return 0; }
-static inline munlock(const void *addr, size_t len) { return 0; }
-
-#endif /* _POSIX_SYS_MMAN_H */
+++ /dev/null
-/*
- * This code is mostly taken from FreeBSD sys/sys/poll.h
- * Changes: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
- *
- ****************************************************************************
- * Copyright (c) 1997 Peter Wemm <peter@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _POSIX_SYS_POLL_H_
-#define _POSIX_SYS_POLL_H_
-
-/*
- * This file is intended to be compatible with the traditional poll.h.
- */
-
-typedef unsigned int nfds_t;
-
-/*
- * This structure is passed as an array to poll(2).
- */
-struct pollfd {
- int fd; /* which file descriptor to poll */
- short events; /* events we are interested in */
- short revents; /* events found on return */
-};
-
-/*
- * Requestable events. If poll(2) finds any of these set, they are
- * copied to revents on return.
- * XXX Note that FreeBSD doesn't make much distinction between POLLPRI
- * and POLLRDBAND since none of the file types have distinct priority
- * bands - and only some have an urgent "mode".
- * XXX Note POLLIN isn't really supported in true SVSV terms. Under SYSV
- * POLLIN includes all of normal, band and urgent data. Most poll handlers
- * on FreeBSD only treat it as "normal" data.
- */
-#define POLLIN 0x0001 /* any readable data available */
-#define POLLPRI 0x0002 /* OOB/Urgent readable data */
-#define POLLOUT 0x0004 /* file descriptor is writeable */
-#define POLLRDNORM 0x0040 /* non-OOB/URG data available */
-#define POLLWRNORM POLLOUT /* no write type differentiation */
-#define POLLRDBAND 0x0080 /* OOB/Urgent readable data */
-#define POLLWRBAND 0x0100 /* OOB/Urgent data can be written */
-
-/*
- * These events are set if they occur regardless of whether they were
- * requested.
- */
-#define POLLERR 0x0008 /* some poll error occurred */
-#define POLLHUP 0x0010 /* file descriptor was "hung up" */
-#define POLLNVAL 0x0020 /* requested events "invalid" */
-
-int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout);
-
-#endif /* _POSIX_SYS_POLL_H_ */
+++ /dev/null
-#ifndef _POSIX_SELECT_H
-#define _POSIX_SELECT_H
-
-#include <sys/time.h>
-int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
-
-#endif /* _POSIX_SELECT_H */
+++ /dev/null
-#ifndef _POSIX_SYS_SOCKET_H_
-#define _POSIX_SYS_SOCKET_H_
-
-#include <fcntl.h>
-#include <lwip/sockets.h>
-
-int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int bind(int s, struct sockaddr *name, socklen_t namelen);
-int shutdown(int s, int how);
-int getpeername (int s, struct sockaddr *name, socklen_t *namelen);
-int getsockname (int s, struct sockaddr *name, socklen_t *namelen);
-int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
-int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
-int close(int s);
-int connect(int s, struct sockaddr *name, socklen_t namelen);
-int listen(int s, int backlog);
-int recv(int s, void *mem, int len, unsigned int flags);
-//int read(int s, void *mem, int len);
-int recvfrom(int s, void *mem, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen);
-int send(int s, void *dataptr, int size, unsigned int flags);
-int sendto(int s, void *dataptr, int size, unsigned int flags,
- struct sockaddr *to, socklen_t tolen);
-int socket(int domain, int type, int protocol);
-//int write(int s, void *dataptr, int size);
-int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
- struct timeval *timeout);
-//int ioctl(int s, long cmd, void *argp);
-int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
-
-#endif /* _POSIX_SYS_SOCKET_H_ */
+++ /dev/null
-#ifndef _POSIX_SYS_STAT_H
-#define _POSIX_SYS_STAT_H
-
-#include_next <sys/stat.h>
-int fstat(int fd, struct stat *buf) asm("fstat64");
-
-#endif /* _POSIX_SYS_STAT_H */
+++ /dev/null
-#ifndef _POSIX_SYSLOG_H
-#define _POSIX_SYSLOG_H
-
-#include <stdarg.h>
-
-#define LOG_PID 0
-#define LOG_CONS 0
-#define LOG_NDELAY 0
-#define LOG_ODELAY 0
-#define LOG_NOWAIT 0
-
-#define LOG_KERN 0
-#define LOG_USER 0
-#define LOG_MAIL 0
-#define LOG_NEWS 0
-#define LOG_UUCP 0
-#define LOG_DAEMON 0
-#define LOG_AUTH 0
-#define LOG_CRON 0
-#define LOG_LPR 0
-
-/* TODO: support */
-#define LOG_EMERG 0
-#define LOG_ALERT 1
-#define LOG_CRIT 2
-#define LOG_ERR 3
-#define LOG_WARNING 4
-#define LOG_NOTICE 5
-#define LOG_INFO 6
-#define LOG_DEBUG 7
-
-void openlog(const char *ident, int option, int facility);
-void syslog(int priority, const char *format, ...);
-void closelog(void);
-void vsyslog(int priority, const char *format, va_list ap);
-
-#endif /* _POSIX_SYSLOG_H */
+++ /dev/null
-#ifndef _POSIX_TERMIOS_H
-#define _POSIX_TERMIOS_H
-
-#define NCC 32
-
-struct termios {
- unsigned long c_iflag;
- unsigned long c_oflag;
- unsigned long c_lflag;
- unsigned long c_cflag;
- unsigned char c_cc[NCC];
-};
-
-/* modem lines */
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RI 0x080
-#define TIOCM_DSR 0x100
-
-/* c_iflag */
-#define IGNBRK 0x00000001
-#define BRKINT 0x00000002
-#define IGNPAR 0x00000004
-#define PARMRK 0x00000008
-#define INPCK 0x00000010
-#define ISTRIP 0x00000020
-#define INLCR 0x00000040
-#define IGNCR 0x00000080
-#define ICRNL 0x00000100
-#define IUCLC 0x00000200
-#define IXON 0x00000400
-#define IXANY 0x00000800
-#define IXOFF 0x00001000
-#define IMAXBEL 0x00002000
-#define IUTF8 0x00004000
-
-/* c_oflag */
-#define OPOST 0x00000001
-#define OLCUC 0x00000002
-#define ONLCR 0x00000004
-#define OCRNL 0x00000008
-#define ONOCR 0x00000010
-#define ONLRET 0x00000020
-#define OFILL 0x00000040
-#define OFDEL 0x00000080
-
-/* c_lflag */
-#define ISIG 0x00000001
-#define ICANON 0x00000002
-#define XCASE 0x00000004
-#define ECHO 0x00000008
-#define ECHOE 0x00000010
-#define ECHOK 0x00000020
-#define ECHONL 0x00000040
-#define NOFLSH 0x00000080
-#define TOSTOP 0x00000100
-#define ECHOCTL 0x00000200
-#define ECHOPRT 0x00000400
-#define ECHOKE 0x00000800
-#define FLUSHO 0x00002000
-#define PENDIN 0x00004000
-#define IEXTEN 0x00008000
-
-/* c_cflag */
-#define CSIZE 0x00000030
-#define CS8 0x00000030
-#define CSTOPB 0x00000040
-#define CREAD 0x00000080
-#define PARENB 0x00000100
-#define PARODD 0x00000200
-#define HUPCL 0x00000400
-#define CLOCAL 0x00000800
-
-/* c_cc */
-#define VTIME 5
-#define VMIN 6
-
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-int tcsetattr(int fildes, int action, const struct termios *tios);
-int tcgetattr(int fildes, struct termios *tios);
-
-#endif /* _POSIX_TERMIOS_H */
+++ /dev/null
-#ifndef _POSIX_TIME_H
-#define _POSIX_TIME_H
-
-#include <sys/time.h>
-#define CLOCK_MONOTONIC 2
-#include_next <time.h>
-
-int nanosleep(const struct timespec *req, struct timespec *rem);
-int clock_gettime(clockid_t clock_id, struct timespec *tp);
-
-#endif /* _POSIX_TIME_H */
+++ /dev/null
-#ifndef _POSIX_UNISTD_H
-#define _POSIX_UNISTD_H
-
-#include_next <unistd.h>
-
-uid_t getuid(void);
-uid_t geteuid(void);
-gid_t getgid(void);
-gid_t getegid(void);
-int gethostname(char *name, size_t namelen);
-size_t getpagesize(void);
-int ftruncate(int fd, off_t length);
-int lockf(int fd, int cmd, off_t len);
-int nice(int inc);
-
-#endif /* _POSIX_UNISTD_H */
+++ /dev/null
-#ifndef __SCHED_H__
-#define __SCHED_H__
-
-#include <mini-os/list.h>
-#include <mini-os/time.h>
-#include <mini-os/arch_sched.h>
-#ifdef HAVE_LIBC
-#include <sys/reent.h>
-#endif
-
-struct thread
-{
- char *name;
- char *stack;
- /* keep in that order */
- unsigned long sp; /* Stack pointer */
- unsigned long ip; /* Instruction pointer */
- MINIOS_TAILQ_ENTRY(struct thread) thread_list;
- uint32_t flags;
- s_time_t wakeup_time;
-#ifdef HAVE_LIBC
- struct _reent reent;
-#endif
-};
-
-extern struct thread *idle_thread;
-void idle_thread_fn(void *unused);
-
-#define RUNNABLE_FLAG 0x00000001
-
-#define is_runnable(_thread) (_thread->flags & RUNNABLE_FLAG)
-#define set_runnable(_thread) (_thread->flags |= RUNNABLE_FLAG)
-#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
-
-#define switch_threads(prev, next) arch_switch_threads(prev, next)
-
- /* Architecture specific setup of thread creation. */
-struct thread* arch_create_thread(char *name, void (*function)(void *),
- void *data);
-
-void init_sched(void);
-void run_idle_thread(void);
-struct thread* create_thread(char *name, void (*function)(void *), void *data);
-void exit_thread(void) __attribute__((noreturn));
-void schedule(void);
-
-#ifdef __INSIDE_MINIOS__
-#define current get_current()
-#endif
-
-void wake(struct thread *thread);
-void block(struct thread *thread);
-void msleep(uint32_t millisecs);
-
-#endif /* __SCHED_H__ */
+++ /dev/null
-#ifndef _SEMAPHORE_H_
-#define _SEMAPHORE_H_
-
-#include <mini-os/wait.h>
-#include <mini-os/spinlock.h>
-
-/*
- * Implementation of semaphore in Mini-os is simple, because
- * there are no preemptive threads, the atomicity is guaranteed.
- */
-
-struct semaphore
-{
- int count;
- struct wait_queue_head wait;
-};
-
-/*
- * the semaphore definition
- */
-struct rw_semaphore {
- signed long count;
- spinlock_t wait_lock;
- int debug;
-};
-
-#define __SEMAPHORE_INITIALIZER(name, n) \
-{ \
- .count = n, \
- .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
-}
-
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
-
-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
-
-static inline void init_SEMAPHORE(struct semaphore *sem, int count)
-{
- sem->count = count;
- init_waitqueue_head(&sem->wait);
-}
-
-#define init_MUTEX(sem) init_SEMAPHORE(sem, 1)
-
-static inline int trydown(struct semaphore *sem)
-{
- unsigned long flags;
- int ret = 0;
- local_irq_save(flags);
- if (sem->count > 0) {
- ret = 1;
- sem->count--;
- }
- local_irq_restore(flags);
- return ret;
-}
-
-static void inline down(struct semaphore *sem)
-{
- unsigned long flags;
- while (1) {
- wait_event(sem->wait, sem->count > 0);
- local_irq_save(flags);
- if (sem->count > 0)
- break;
- local_irq_restore(flags);
- }
- sem->count--;
- local_irq_restore(flags);
-}
-
-static void inline up(struct semaphore *sem)
-{
- unsigned long flags;
- local_irq_save(flags);
- sem->count++;
- wake_up(&sem->wait);
- local_irq_restore(flags);
-}
-
-/* FIXME! Thre read/write semaphores are unimplemented! */
-static inline void init_rwsem(struct rw_semaphore *sem)
-{
- sem->count = 1;
-}
-
-static inline void down_read(struct rw_semaphore *sem)
-{
-}
-
-
-static inline void up_read(struct rw_semaphore *sem)
-{
-}
-
-static inline void up_write(struct rw_semaphore *sem)
-{
-}
-
-static inline void down_write(struct rw_semaphore *sem)
-{
-}
-
-#endif /* _SEMAPHORE_H */
+++ /dev/null
-#ifndef __ASM_SPINLOCK_H
-#define __ASM_SPINLOCK_H
-
-#include <mini-os/lib.h>
-
-/*
- * Your basic SMP spinlocks, allowing only a single CPU anywhere
- */
-
-typedef struct {
- volatile unsigned int slock;
-} spinlock_t;
-
-
-#include <mini-os/arch_spinlock.h>
-
-
-#define SPINLOCK_MAGIC 0xdead4ead
-
-#define SPIN_LOCK_UNLOCKED ARCH_SPIN_LOCK_UNLOCKED
-
-#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
-
-/*
- * Simple spin lock operations. There are two variants, one clears IRQ's
- * on the local processor, one does not.
- *
- * We make no fairness assumptions. They have a cost.
- */
-
-#define spin_is_locked(x) arch_spin_is_locked(x)
-
-#define spin_unlock_wait(x) arch_spin_unlock_wait(x)
-
-
-#define _spin_trylock(lock) ({_raw_spin_trylock(lock) ? \
- 1 : ({ 0;});})
-
-#define _spin_lock(lock) \
-do { \
- _raw_spin_lock(lock); \
-} while(0)
-
-#define _spin_unlock(lock) \
-do { \
- _raw_spin_unlock(lock); \
-} while (0)
-
-
-#define spin_lock(lock) _spin_lock(lock)
-#define spin_unlock(lock) _spin_unlock(lock)
-
-#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
-
-#endif
+++ /dev/null
-#ifndef _MINIOS_SYS_LOCK_H_
-#define _MINIOS_SYS_LOCK_H_
-
-#ifdef HAVE_LIBC
-
-/* Due to inclusion loop, we can not include sched.h, so have to hide things */
-
-#include <mini-os/waittypes.h>
-
-
-typedef struct {
- int busy;
- struct wait_queue_head wait;
-} _LOCK_T;
-
-#define __LOCK_INIT(class,lock) \
- class _LOCK_T lock = { .wait = __WAIT_QUEUE_HEAD_INITIALIZER(lock.wait) }
-int ___lock_init(_LOCK_T *lock);
-int ___lock_acquire(_LOCK_T *lock);
-int ___lock_try_acquire(_LOCK_T *lock);
-int ___lock_release(_LOCK_T *lock);
-int ___lock_close(_LOCK_T *lock);
-#define __lock_init(__lock) ___lock_init(&__lock)
-#define __lock_acquire(__lock) ___lock_acquire(&__lock)
-#define __lock_release(__lock) ___lock_release(&__lock)
-#define __lock_try_acquire(__lock) ___lock_try_acquire(&__lock)
-#define __lock_close(__lock) 0
-
-
-typedef struct {
- struct thread *owner;
- int count;
- struct wait_queue_head wait;
-} _LOCK_RECURSIVE_T;
-
-#define __LOCK_INIT_RECURSIVE(class, lock) \
- class _LOCK_RECURSIVE_T lock = { .wait = __WAIT_QUEUE_HEAD_INITIALIZER((lock).wait) }
-
-int ___lock_init_recursive(_LOCK_RECURSIVE_T *lock);
-int ___lock_acquire_recursive(_LOCK_RECURSIVE_T *lock);
-int ___lock_try_acquire_recursive(_LOCK_RECURSIVE_T *lock);
-int ___lock_release_recursive(_LOCK_RECURSIVE_T *lock);
-int ___lock_close_recursive(_LOCK_RECURSIVE_T *lock);
-#define __lock_init_recursive(__lock) ___lock_init_recursive(&__lock)
-#define __lock_acquire_recursive(__lock) ___lock_acquire_recursive(&__lock)
-#define __lock_release_recursive(__lock) ___lock_release_recursive(&__lock)
-#define __lock_try_acquire_recursive(__lock) ___lock_try_acquire_recursive(&__lock)
-#define __lock_close_recursive(__lock) 0
-
-#endif
-
-#endif /* _MINIOS_SYS_LOCK_H_ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: time.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- * Robert Kaiser (kaiser@informatik.fh-wiesbaden.de)
- *
- * Date: Jul 2003, changes: Jun 2005, Sep 2006
- *
- * Environment: Xen Minimal OS
- * Description: Time and timer functions
- *
- ****************************************************************************
- */
-
-#ifndef _MINIOS_SYS_TIME_H_
-#define _MINIOS_SYS_TIME_H_
-
-#ifdef HAVE_LIBC
-#include_next <sys/time.h>
-
-#else
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-struct timezone {
-};
-
-struct timeval {
- time_t tv_sec; /* seconds */
- suseconds_t tv_usec; /* microseconds */
-};
-
-int gettimeofday(struct timeval *tv, void *tz);
-
-#endif
-#ifdef HAVE_LIBC
-#include <sys/select.h>
-#endif
-
-#endif /* _MINIOS_SYS_TIME_H_ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: time.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- * Robert Kaiser (kaiser@informatik.fh-wiesbaden.de)
- *
- * Date: Jul 2003, changes: Jun 2005, Sep 2006
- *
- * Environment: Xen Minimal OS
- * Description: Time and timer functions
- *
- ****************************************************************************
- */
-
-#ifndef _MINIOS_TIME_H_
-#define _MINIOS_TIME_H_
-#include <mini-os/types.h>
-
-/*
- * System Time
- * 64 bit value containing the nanoseconds elapsed since boot time.
- * This value is adjusted by frequency drift.
- * NOW() returns the current time.
- * The other macros are for convenience to approximate short intervals
- * of real time into system time
- */
-typedef int64_t s_time_t;
-#define NOW() ((s_time_t)monotonic_clock())
-#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL )
-#define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL )
-#define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL )
-#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000UL )
-#define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL )
-#define Time_Max ((s_time_t) 0x7fffffffffffffffLL)
-#define FOREVER Time_Max
-#define NSEC_TO_USEC(_nsec) ((_nsec) / 1000UL)
-#define NSEC_TO_MSEC(_nsec) ((_nsec) / 1000000ULL)
-#define NSEC_TO_SEC(_nsec) ((_nsec) / 1000000000ULL)
-
-/* wall clock time */
-typedef long time_t;
-typedef long suseconds_t;
-
-#include <sys/time.h>
-
-#ifdef HAVE_LIBC
-#include_next <time.h>
-#endif
-
-/* prototypes */
-void init_time(void);
-void fini_time(void);
-s_time_t get_s_time(void);
-s_time_t get_v_time(void);
-uint64_t monotonic_clock(void);
-void block_domain(s_time_t until);
-
-#endif /* _MINIOS_TIME_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/char/tpm.c
- * from the linux kernel
- *
- * Copyright (C) 2004 IBM Corporation
- *
- * This code has also been derived from drivers/char/tpm/tpm_tis.c
- * from the linux kernel
- *
- * Copyright (C) 2005, 2006 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, version 2
- * of the License
- */
-#ifndef TPM_TIS_H
-#define TPM_TIS_H
-
-#include <mini-os/types.h>
-#include <mini-os/byteorder.h>
-
-#define TPM_TIS_EN_LOCL0 1
-#define TPM_TIS_EN_LOCL1 (1 << 1)
-#define TPM_TIS_EN_LOCL2 (1 << 2)
-#define TPM_TIS_EN_LOCL3 (1 << 3)
-#define TPM_TIS_EN_LOCL4 (1 << 4)
-#define TPM_TIS_EN_LOCLALL (TPM_TIS_EN_LOCL0 | TPM_TIS_EN_LOCL1 | TPM_TIS_EN_LOCL2 | TPM_TIS_EN_LOCL3 | TPM_TIS_EN_LOCL4)
-#define TPM_TIS_LOCL_INT_TO_FLAG(x) (1 << x)
-#define TPM_BASEADDR 0xFED40000
-#define TPM_PROBE_IRQ 0xFFFF
-
-struct tpm_chip;
-
-struct tpm_chip* init_tpm_tis(unsigned long baseaddr, int localities, unsigned int irq);
-struct tpm_chip* init_tpm2_tis(unsigned long baseaddr, int localities, unsigned int irq);
-void shutdown_tpm_tis(struct tpm_chip* tpm);
-
-int tpm_tis_request_locality(struct tpm_chip* tpm, int locality);
-int tpm_tis_cmd(struct tpm_chip* tpm, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen);
-
-#ifdef HAVE_LIBC
-#include <sys/stat.h>
-#include <fcntl.h>
-/* POSIX IO functions:
- * use tpm_tis_open() to get a file descriptor to the tpm device
- * use write() on the fd to send a command to the backend. You must
- * include the entire command in a single call to write().
- * use read() on the fd to read the response. You can use
- * fstat() to get the size of the response and lseek() to seek on it.
- */
-int tpm_tis_open(struct tpm_chip* tpm);
-int tpm_tis_posix_read(int fd, uint8_t* buf, size_t count);
-int tpm_tis_posix_write(int fd, const uint8_t* buf, size_t count);
-int tpm_tis_posix_fstat(int fd, struct stat* buf);
-#endif
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/xen/tpmback/tpmback.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself derived from drivers/xen/netback/netback.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This code has also been derived from drivers/xen/tpmback/xenbus.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (C) 2005 IBM Corporation
- * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
- *
- * This code has also been derived from drivers/xen/tpmback/interface.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself also derived from drvivers/xen/netback/interface.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2004, Keir Fraser
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, version 2
- * of the License
- */
-
-#include <xen/io/tpmif.h>
-#include <xen/io/xenbus.h>
-#include <mini-os/types.h>
-#include <xen/xen.h>
-#ifndef TPMBACK_H
-#define TPMBACK_H
-
-struct tpmcmd {
- domid_t domid; /* Domid of the frontend */
- uint8_t locality; /* Locality requested by the frontend */
- unsigned int handle; /* Handle of the frontend */
- void *opaque; /* Opaque pointer taken from the tpmback instance */
-
- uint8_t* req; /* tpm command bits, allocated by driver, DON'T FREE IT */
- unsigned int req_len; /* Size of the command in buf - set by tpmback driver */
- unsigned int resp_len; /* Size of the outgoing command,
- you set this before passing the cmd object to tpmback_resp */
- uint8_t* resp; /* Buffer for response - YOU MUST ALLOCATE IT, YOU MUST ALSO FREE IT */
-};
-typedef struct tpmcmd tpmcmd_t;
-
-/* Initialize the tpm backend driver */
-void init_tpmback(void (*open_cb)(domid_t, unsigned int), void (*close_cb)(domid_t, unsigned int));
-
-/* Shutdown tpm backend driver */
-void shutdown_tpmback(void);
-
-/* Blocks until a tpm command is sent from any front end.
- * Returns a pointer to the tpm command to handle.
- * Do not try to free this pointer or the req buffer
- * This function will return NULL if the tpm backend driver
- * is shutdown or any other error occurs */
-tpmcmd_t* tpmback_req_any(void);
-
-/* Blocks until a tpm command from the frontend at domid/handle
- * is sent.
- * Returns NULL if domid/handle is not connected, tpmback is
- * shutdown or shutting down, or if there is an error
- */
-tpmcmd_t* tpmback_req(domid_t domid, unsigned int handle);
-
-/* Send the response to the tpm command back to the frontend
- * This function will free the tpmcmd object, but you must free the resp
- * buffer yourself */
-void tpmback_resp(tpmcmd_t* tpmcmd);
-
-/* Waits for the first frontend to connect and then sets domid and handle appropriately.
- * If one or more frontends are already connected, this will set domid and handle to one
- * of them arbitrarily. The main use for this function is to wait until a single
- * frontend connection has occured.
- * returns 0 on success, non-zero on failure */
-int tpmback_wait_for_frontend_connect(domid_t *domid, unsigned int *handle);
-
-/* returns the number of frontends connected */
-int tpmback_num_frontends(void);
-
-/* Returns the uuid of the specified frontend, NULL on error.
- * The return value is internally allocated, so don't free it */
-unsigned char* tpmback_get_uuid(domid_t domid, unsigned int handle);
-
-/* Get and set the opaque pointer for a tpmback instance */
-void* tpmback_get_opaque(domid_t domid, unsigned int handle);
-/* Returns zero if successful, nonzero on failure (no such frontend) */
-int tpmback_set_opaque(domid_t domid, unsigned int handle, void* opaque);
-
-/* Get the XSM context of the given domain (using the tpmback event channel) */
-int tpmback_get_peercontext(domid_t domid, unsigned int handle, void* buffer, int buflen);
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/char/tpm_vtpm.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (C) 2006 IBM Corporation
- *
- * This code has also been derived from drivers/char/tpm_xen.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself derived from drivers/xen/netfront/netfront.c
- * from the linux kernel
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- */
-#ifndef TPMFRONT_H
-#define TPMFRONT_H
-
-#include <mini-os/types.h>
-#include <mini-os/os.h>
-#include <mini-os/events.h>
-#include <mini-os/wait.h>
-#include <xen/xen.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/tpmif.h>
-
-struct tpmfront_dev {
- grant_ref_t ring_ref;
- evtchn_port_t evtchn;
-
- tpmif_shared_page_t *page;
-
- domid_t bedomid;
- char* nodename;
- char* bepath;
-
- XenbusState state;
-
- uint8_t waiting;
- struct wait_queue_head waitq;
-
- uint8_t* respbuf;
- size_t resplen;
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-
-};
-
-
-/*Initialize frontend */
-struct tpmfront_dev* init_tpmfront(const char* nodename);
-/*Shutdown frontend */
-void shutdown_tpmfront(struct tpmfront_dev* dev);
-
-/* Send a tpm command to the backend and wait for the response
- *
- * @dev - frontend device
- * @req - request buffer
- * @reqlen - length of request buffer
- * @resp - *resp will be set to internal response buffer, don't free it! Value is undefined on error
- * @resplen - *resplen will be set to the length of the response. Value is undefined on error
- *
- * returns 0 on success, non zero on failure.
- * */
-int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen);
-
-/* Set the locality used for communicating with a vTPM */
-int tpmfront_set_locality(struct tpmfront_dev* dev, int locality);
-
-#ifdef HAVE_LIBC
-#include <sys/stat.h>
-/* POSIX IO functions:
- * use tpmfront_open() to get a file descriptor to the tpm device
- * use write() on the fd to send a command to the backend. You must
- * include the entire command in a single call to write().
- * use read() on the fd to read the response. You can use
- * fstat() to get the size of the response and lseek() to seek on it.
- */
-int tpmfront_open(struct tpmfront_dev* dev);
-int tpmfront_posix_read(int fd, uint8_t* buf, size_t count);
-int tpmfront_posix_write(int fd, const uint8_t* buf, size_t count);
-int tpmfront_posix_fstat(int fd, struct stat* buf);
-#endif
-
-
-#endif
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: types.h
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes:
- *
- * Date: May 2003
- *
- * Environment: Xen Minimal OS
- * Description: a random collection of type definitions
- *
- ****************************************************************************
- * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $
- ****************************************************************************
- */
-
-#ifndef _TYPES_H_
-#define _TYPES_H_
-#include <stddef.h>
-
-/* FreeBSD compat types */
-#ifndef HAVE_LIBC
-typedef unsigned char u_char;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-#endif
-#if defined(__i386__) || defined(__arm__)
-typedef long long quad_t;
-typedef unsigned long long u_quad_t;
-#elif defined(__x86_64__)
-typedef long quad_t;
-typedef unsigned long u_quad_t;
-#endif /* __i386__ || __x86_64__ */
-
-#ifdef HAVE_LIBC
-#include <limits.h>
-#include <stdint.h>
-#else
-#if defined(__i386__) || defined(__arm__)
-typedef unsigned int uintptr_t;
-typedef int intptr_t;
-#elif defined(__x86_64__) || defined(__aarch64__)
-typedef unsigned long uintptr_t;
-typedef long intptr_t;
-#endif /* __i386__ || __x86_64__ */
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-typedef unsigned short uint16_t;
-typedef signed short int16_t;
-typedef unsigned int uint32_t;
-typedef signed int int32_t;
-#if defined(__i386__) || defined(__arm__)
-typedef signed long long int64_t;
-typedef unsigned long long uint64_t;
-#elif defined(__x86_64__) || defined(__aarch64__)
-typedef signed long int64_t;
-typedef unsigned long uint64_t;
-#endif
-typedef uint64_t uintmax_t;
-typedef int64_t intmax_t;
-typedef int64_t off_t;
-#endif
-
-typedef intptr_t ptrdiff_t;
-
-
-#ifndef HAVE_LIBC
-typedef long ssize_t;
-#endif
-
-#endif /* _TYPES_H_ */
+++ /dev/null
-#ifndef __WAIT_H__
-#define __WAIT_H__
-
-#include <mini-os/sched.h>
-#include <mini-os/os.h>
-#include <mini-os/waittypes.h>
-
-#define DEFINE_WAIT(name) \
-struct wait_queue name = { \
- .thread = get_current(), \
- .waiting = 0, \
-}
-
-
-static inline void init_waitqueue_head(struct wait_queue_head *h)
-{
- MINIOS_STAILQ_INIT(h);
-}
-
-static inline void init_waitqueue_entry(struct wait_queue *q, struct thread *thread)
-{
- q->thread = thread;
- q->waiting = 0;
-}
-
-static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue *q)
-{
- if (!q->waiting) {
- MINIOS_STAILQ_INSERT_HEAD(h, q, thread_list);
- q->waiting = 1;
- }
-}
-
-static inline void remove_wait_queue(struct wait_queue_head *h, struct wait_queue *q)
-{
- if (q->waiting) {
- MINIOS_STAILQ_REMOVE(h, q, struct wait_queue, thread_list);
- q->waiting = 0;
- }
-}
-
-static inline void wake_up(struct wait_queue_head *head)
-{
- unsigned long flags;
- struct wait_queue *curr, *tmp;
- local_irq_save(flags);
- MINIOS_STAILQ_FOREACH_SAFE(curr, head, thread_list, tmp)
- wake(curr->thread);
- local_irq_restore(flags);
-}
-
-#define add_waiter(w, wq) do { \
- unsigned long flags; \
- local_irq_save(flags); \
- add_wait_queue(&wq, &w); \
- block(get_current()); \
- local_irq_restore(flags); \
-} while (0)
-
-#define remove_waiter(w, wq) do { \
- unsigned long flags; \
- local_irq_save(flags); \
- remove_wait_queue(&wq, &w); \
- local_irq_restore(flags); \
-} while (0)
-
-#define wait_event_deadline(wq, condition, deadline) do { \
- unsigned long flags; \
- DEFINE_WAIT(__wait); \
- if(condition) \
- break; \
- for(;;) \
- { \
- /* protect the list */ \
- local_irq_save(flags); \
- add_wait_queue(&wq, &__wait); \
- get_current()->wakeup_time = deadline; \
- clear_runnable(get_current()); \
- local_irq_restore(flags); \
- if((condition) || (deadline && NOW() >= deadline)) \
- break; \
- schedule(); \
- } \
- local_irq_save(flags); \
- /* need to wake up */ \
- wake(get_current()); \
- remove_wait_queue(&wq, &__wait); \
- local_irq_restore(flags); \
-} while(0)
-
-#define wait_event(wq, condition) wait_event_deadline(wq, condition, 0)
-
-
-
-#endif /* __WAIT_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-#ifndef __WAITTYPE_H__
-#define __WAITTYPE_H__
-
-#include <mini-os/list.h>
-
-struct thread;
-struct wait_queue
-{
- int waiting;
- struct thread *thread;
- MINIOS_STAILQ_ENTRY(struct wait_queue) thread_list;
-};
-
-/* TODO - lock required? */
-MINIOS_STAILQ_HEAD(wait_queue_head, struct wait_queue);
-
-#define DECLARE_WAIT_QUEUE_HEAD(name) \
- struct wait_queue_head name = MINIOS_STAILQ_HEAD_INITIALIZER(name)
-
-#define __WAIT_QUEUE_HEAD_INITIALIZER(name) MINIOS_STAILQ_HEAD_INITIALIZER(name)
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-#ifndef ARCH_ENDIAN_H
-#error "Do not include arch_endian by itself, include endian.h"
-#else
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-#endif
+++ /dev/null
-
-#ifndef __ARCH_LIMITS_H__
-#define __ARCH_LIMITS_H__
-
-#define __PAGE_SHIFT 12
-
-#ifdef __ASSEMBLY__
-#define __PAGE_SIZE (1 << __PAGE_SHIFT)
-#else
-#ifdef __x86_64__
-#define __PAGE_SIZE (1UL << __PAGE_SHIFT)
-#else
-#define __PAGE_SIZE (1ULL << __PAGE_SHIFT)
-#endif
-#endif
-
-#define __STACK_SIZE_PAGE_ORDER 4
-#define __STACK_SIZE (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER))
-
-#endif /* __ARCH_LIMITS_H__ */
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- *
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * Copyright (c) 2005, Keir A Fraser
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _ARCH_MM_H_
-#define _ARCH_MM_H_
-
-#ifndef __ASSEMBLY__
-#include <xen/xen.h>
-#if defined(__i386__)
-#include <xen/arch-x86_32.h>
-#elif defined(__x86_64__)
-#include <xen/arch-x86_64.h>
-#else
-#error "Unsupported architecture"
-#endif
-#endif
-
-#define L1_FRAME 1
-#define L2_FRAME 2
-#define L3_FRAME 3
-
-#define L1_PAGETABLE_SHIFT 12
-
-#if defined(__i386__)
-
-#define L2_PAGETABLE_SHIFT 21
-#define L3_PAGETABLE_SHIFT 30
-
-#define L1_PAGETABLE_ENTRIES 512
-#define L2_PAGETABLE_ENTRIES 512
-#define L3_PAGETABLE_ENTRIES 4
-
-#define PADDR_BITS 44
-#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
-
-#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
-
-/*
- * If starting from virtual address greater than 0xc0000000,
- * this value will be 2 to account for final mid-level page
- * directory which is always mapped in at this location.
- */
-#define NOT_L1_FRAMES 3
-#define PRIpte "016llx"
-#ifndef __ASSEMBLY__
-typedef uint64_t pgentry_t;
-#endif
-
-#elif defined(__x86_64__)
-
-#define L2_PAGETABLE_SHIFT 21
-#define L3_PAGETABLE_SHIFT 30
-#define L4_PAGETABLE_SHIFT 39
-
-#define L1_PAGETABLE_ENTRIES 512
-#define L2_PAGETABLE_ENTRIES 512
-#define L3_PAGETABLE_ENTRIES 512
-#define L4_PAGETABLE_ENTRIES 512
-
-/* These are page-table limitations. Current CPUs support only 40-bit phys. */
-#define PADDR_BITS 52
-#define VADDR_BITS 48
-#define PADDR_MASK ((1UL << PADDR_BITS)-1)
-#define VADDR_MASK ((1UL << VADDR_BITS)-1)
-
-#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
-#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)
-
-#define NOT_L1_FRAMES 3
-#define PRIpte "016lx"
-#ifndef __ASSEMBLY__
-typedef unsigned long pgentry_t;
-#endif
-
-#endif
-
-#define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1)
-
-/* Given a virtual address, get an entry offset into a page table. */
-#define l1_table_offset(_a) \
- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
-#define l2_table_offset(_a) \
- (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
-#define l3_table_offset(_a) \
- (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
-#if defined(__x86_64__)
-#define l4_table_offset(_a) \
- (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
-#endif
-
-#define _PAGE_PRESENT 0x001ULL
-#define _PAGE_RW 0x002ULL
-#define _PAGE_USER 0x004ULL
-#define _PAGE_PWT 0x008ULL
-#define _PAGE_PCD 0x010ULL
-#define _PAGE_ACCESSED 0x020ULL
-#define _PAGE_DIRTY 0x040ULL
-#define _PAGE_PAT 0x080ULL
-#define _PAGE_PSE 0x080ULL
-#define _PAGE_GLOBAL 0x100ULL
-
-#if defined(__i386__)
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L1_PROT_RO (_PAGE_PRESENT|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
-#define L3_PROT (_PAGE_PRESENT)
-#elif defined(__x86_64__)
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
-#define L1_PROT_RO (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_USER)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#endif /* __i386__ || __x86_64__ */
-
-/* flags for ioremap */
-#define IO_PROT (L1_PROT)
-#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
-
-/* for P2M */
-#define INVALID_P2M_ENTRY (~0UL)
-
-#include "arch_limits.h"
-#define PAGE_SIZE __PAGE_SIZE
-#define PAGE_SHIFT __PAGE_SHIFT
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
-#define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT)
-#define PFN_PHYS(x) ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
-#define PHYS_PFN(x) ((x) >> L1_PAGETABLE_SHIFT)
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-#ifndef __ASSEMBLY__
-/* Definitions for machine and pseudophysical addresses. */
-#ifdef __i386__
-typedef unsigned long long paddr_t;
-typedef unsigned long long maddr_t;
-#else
-typedef unsigned long paddr_t;
-typedef unsigned long maddr_t;
-#endif
-
-extern unsigned long *phys_to_machine_mapping;
-extern char _text, _etext, _erodata, _edata, _end;
-extern unsigned long mfn_zero;
-#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
-static __inline__ maddr_t phys_to_machine(paddr_t phys)
-{
- maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
- machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
- return machine;
-}
-
-#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
-static __inline__ paddr_t machine_to_phys(maddr_t machine)
-{
- paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
- phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
- return phys;
-}
-#endif
-
-#define VIRT_START ((unsigned long)&_text)
-
-#define to_phys(x) ((unsigned long)(x)-VIRT_START)
-#define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START))
-
-#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
-#define virt_to_mfn(_virt) (pfn_to_mfn(virt_to_pfn(_virt)))
-#define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach)))
-#define virt_to_mach(_virt) (phys_to_machine(to_phys(_virt)))
-#define mfn_to_virt(_mfn) (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
-#define pfn_to_virt(_pfn) (to_virt((_pfn) << PAGE_SHIFT))
-
-/* Pagetable walking. */
-#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
-#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
-
-
-#define PT_BASE ((pgentry_t *)start_info.pt_base)
-
-#ifdef __x86_64__
-#define virtual_to_l3(_virt) ((pgentry_t *)pte_to_virt(PT_BASE[l4_table_offset(_virt)]))
-#else
-#define virtual_to_l3(_virt) PT_BASE
-#endif
-
-#define virtual_to_l2(_virt) ({ \
- unsigned long __virt2 = (_virt); \
- (pgentry_t *) pte_to_virt(virtual_to_l3(__virt2)[l3_table_offset(__virt2)]); \
-})
-
-#define virtual_to_l1(_virt) ({ \
- unsigned long __virt1 = (_virt); \
- (pgentry_t *) pte_to_virt(virtual_to_l2(__virt1)[l2_table_offset(__virt1)]); \
-})
-
-#define virtual_to_pte(_virt) ({ \
- unsigned long __virt0 = (unsigned long) (_virt); \
- virtual_to_l1(__virt0)[l1_table_offset(__virt0)]; \
-})
-#define virtual_to_mfn(_virt) pte_to_mfn(virtual_to_pte(_virt))
-
-#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, NULL, L1_PROT)
-#define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, NULL, L1_PROT_RO)
-#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, NULL, L1_PROT_RO)
-
-pgentry_t *need_pgt(unsigned long addr);
-
-#endif /* _ARCH_MM_H_ */
+++ /dev/null
-
-#ifndef __ARCH_SCHED_H__
-#define __ARCH_SCHED_H__
-
-#include "arch_limits.h"
-
-static inline struct thread* get_current(void)
-{
- struct thread **current;
-#ifdef __i386__
- register unsigned long sp asm("esp");
-#else
- register unsigned long sp asm("rsp");
-#endif
- current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1));
- return *current;
-}
-
-extern void __arch_switch_threads(unsigned long *prevctx, unsigned long *nextctx);
-
-#define arch_switch_threads(prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp)
-
-
-
-#endif /* __ARCH_SCHED_H__ */
+++ /dev/null
-
-
-#ifndef __ARCH_ASM_SPINLOCK_H
-#define __ARCH_ASM_SPINLOCK_H
-
-#include <mini-os/lib.h>
-#include "os.h"
-
-
-#define ARCH_SPIN_LOCK_UNLOCKED { 1 }
-
-/*
- * Simple spin lock operations. There are two variants, one clears IRQ's
- * on the local processor, one does not.
- *
- * We make no fairness assumptions. They have a cost.
- */
-
-#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0)
-#define arch_spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
-
-#define spin_lock_string \
- "1:\n" \
- LOCK \
- "decb %0\n\t" \
- "jns 3f\n" \
- "2:\t" \
- "rep;nop\n\t" \
- "cmpb $0,%0\n\t" \
- "jle 2b\n\t" \
- "jmp 1b\n" \
- "3:\n\t"
-
-#define spin_lock_string_flags \
- "1:\n" \
- LOCK \
- "decb %0\n\t" \
- "jns 4f\n\t" \
- "2:\t" \
- "testl $0x200, %1\n\t" \
- "jz 3f\n\t" \
- "#sti\n\t" \
- "3:\t" \
- "rep;nop\n\t" \
- "cmpb $0, %0\n\t" \
- "jle 3b\n\t" \
- "#cli\n\t" \
- "jmp 1b\n" \
- "4:\n\t"
-
-/*
- * This works. Despite all the confusion.
- * (except on PPro SMP or if we are using OOSTORE)
- * (PPro errata 66, 92)
- */
-
-#define spin_unlock_string \
- "xchgb %b0, %1" \
- :"=q" (oldval), "=m" (lock->slock) \
- :"0" (oldval) : "memory"
-
-static inline void _raw_spin_unlock(spinlock_t *lock)
-{
- char oldval = ARCH_SPIN_LOCK_UNLOCKED;
- __asm__ __volatile__(
- spin_unlock_string
- );
-}
-
-static inline int _raw_spin_trylock(spinlock_t *lock)
-{
- char oldval;
- __asm__ __volatile__(
- "xchgb %b0,%1\n"
- :"=q" (oldval), "=m" (lock->slock)
- :"0" (0) : "memory");
- return oldval > 0;
-}
-
-static inline void _raw_spin_lock(spinlock_t *lock)
-{
- __asm__ __volatile__(
- spin_lock_string
- :"=m" (lock->slock) : : "memory");
-}
-
-static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
-{
- __asm__ __volatile__(
- spin_lock_string_flags
- :"=m" (lock->slock) : "r" (flags) : "memory");
-}
-
-#endif
+++ /dev/null
-/******************************************************************************
- * os.h
- *
- * random collection of macros and definition
- */
-
-#ifndef _OS_H_
-#define _OS_H_
-
-#define smp_processor_id() 0
-
-
-#ifndef __ASSEMBLY__
-#include <mini-os/compiler.h>
-#include <mini-os/types.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/kernel.h>
-#include <xen/xsm/flask_op.h>
-
-#define USED __attribute__ ((used))
-
-#define BUG do_exit
-
-#endif
-#include <xen/xen.h>
-
-
-
-#define __KERNEL_CS FLAT_KERNEL_CS
-#define __KERNEL_DS FLAT_KERNEL_DS
-#define __KERNEL_SS FLAT_KERNEL_SS
-
-#define TRAP_divide_error 0
-#define TRAP_debug 1
-#define TRAP_nmi 2
-#define TRAP_int3 3
-#define TRAP_overflow 4
-#define TRAP_bounds 5
-#define TRAP_invalid_op 6
-#define TRAP_no_device 7
-#define TRAP_double_fault 8
-#define TRAP_copro_seg 9
-#define TRAP_invalid_tss 10
-#define TRAP_no_segment 11
-#define TRAP_stack_error 12
-#define TRAP_gp_fault 13
-#define TRAP_page_fault 14
-#define TRAP_spurious_int 15
-#define TRAP_copro_error 16
-#define TRAP_alignment_check 17
-#define TRAP_machine_check 18
-#define TRAP_simd_error 19
-#define TRAP_deferred_nmi 31
-
-/* Everything below this point is not included by assembler (.S) files. */
-#ifndef __ASSEMBLY__
-
-extern shared_info_t *HYPERVISOR_shared_info;
-
-void trap_init(void);
-void trap_fini(void);
-
-void arch_fini(void);
-
-
-
-
-
-/*
- * The use of 'barrier' in the following reflects their use as local-lock
- * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
- * critical operations are executed. All critical operations must complete
- * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
- * includes these barriers, for example.
- */
-
-#define __cli() \
-do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- _vcpu->evtchn_upcall_mask = 1; \
- barrier(); \
-} while (0)
-
-#define __sti() \
-do { \
- vcpu_info_t *_vcpu; \
- barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- _vcpu->evtchn_upcall_mask = 0; \
- barrier(); /* unmask then check (avoid races) */ \
- if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
- force_evtchn_callback(); \
-} while (0)
-
-#define __save_flags(x) \
-do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- (x) = _vcpu->evtchn_upcall_mask; \
-} while (0)
-
-#define __restore_flags(x) \
-do { \
- vcpu_info_t *_vcpu; \
- barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
- barrier(); /* unmask then check (avoid races) */ \
- if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
- force_evtchn_callback(); \
- }\
-} while (0)
-
-#define safe_halt() ((void)0)
-
-#define __save_and_cli(x) \
-do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- (x) = _vcpu->evtchn_upcall_mask; \
- _vcpu->evtchn_upcall_mask = 1; \
- barrier(); \
-} while (0)
-
-#define local_irq_save(x) __save_and_cli(x)
-#define local_irq_restore(x) __restore_flags(x)
-#define local_save_flags(x) __save_flags(x)
-#define local_irq_disable() __cli()
-#define local_irq_enable() __sti()
-
-#define irqs_disabled() \
- HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].evtchn_upcall_mask
-
-/* This is a barrier for the compiler only, NOT the processor! */
-#define barrier() __asm__ __volatile__("": : :"memory")
-
-#if defined(__i386__)
-#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
-#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
-#define wmb() __asm__ __volatile__ ("": : :"memory")
-#elif defined(__x86_64__)
-#define mb() __asm__ __volatile__ ("mfence":::"memory")
-#define rmb() __asm__ __volatile__ ("lfence":::"memory")
-#define wmb() __asm__ __volatile__ ("sfence" ::: "memory") /* From CONFIG_UNORDERED_IO (linux) */
-#endif
-
-
-#define LOCK_PREFIX ""
-#define LOCK ""
-#define ADDR (*(volatile long *) addr)
-/*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */
-typedef struct { volatile int counter; } atomic_t;
-
-
-/************************** i386 *******************************/
-#ifdef __INSIDE_MINIOS__
-#if defined (__i386__)
-
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((struct __xchg_dummy *)(x))
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is atomic and cannot be reordered.
- * It can be reorderdered on other architectures other than x86.
- * It also implies a memory barrier.
- */
-static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
-{
- int oldbit;
-
- __asm__ __volatile__( LOCK
- "btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr) : "memory");
- return oldbit;
-}
-
-static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
-{
- return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
-}
-
-static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
-{
- int oldbit;
-
- __asm__ __volatile__(
- "btl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit)
- :"m" (ADDR),"Ir" (nr));
- return oldbit;
-}
-
-#define test_bit(nr,addr) \
-(__builtin_constant_p(nr) ? \
- constant_test_bit((nr),(addr)) : \
- variable_test_bit((nr),(addr)))
-
-/**
- * set_bit - Atomically set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This function is atomic and may not be reordered. See __set_bit()
- * if you do not require the atomic guarantees.
- *
- * Note: there are no guarantees that this function will not be reordered
- * on non x86 architectures, so if you are writting portable code,
- * make sure not to rely on its reordering guarantees.
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static inline void set_bit(int nr, volatile unsigned long * addr)
-{
- __asm__ __volatile__( LOCK
- "btsl %1,%0"
- :"=m" (ADDR)
- :"Ir" (nr));
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * clear_bit() is atomic and may not be reordered. However, it does
- * not contain a memory barrier, so if it is used for locking purposes,
- * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
- * in order to ensure changes are visible on other processors.
- */
-static inline void clear_bit(int nr, volatile unsigned long * addr)
-{
- __asm__ __volatile__( LOCK
- "btrl %1,%0"
- :"=m" (ADDR)
- :"Ir" (nr));
-}
-
-/**
- * __ffs - find first bit in word.
- * @word: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static inline unsigned long __ffs(unsigned long word)
-{
- __asm__("bsfl %1,%0"
- :"=r" (word)
- :"rm" (word));
- return word;
-}
-
-
-/*
- * These have to be done with inline assembly: that way the bit-setting
- * is guaranteed to be atomic. All bit operations return 0 if the bit
- * was cleared before the operation and != 0 if it was not.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-#define ADDR (*(volatile long *) addr)
-
-#define rdtscll(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
-
-
-
-#elif defined(__x86_64__)/* ifdef __i386__ */
-/************************** x86_84 *******************************/
-
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-#define __xg(x) ((volatile long *)(x))
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %k0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 8:
- __asm__ __volatile__("xchgq %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is atomic and cannot be reordered.
- * It also implies a memory barrier.
- */
-static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
-{
- int oldbit;
-
- __asm__ __volatile__( LOCK_PREFIX
- "btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr) : "memory");
- return oldbit;
-}
-
-static __inline__ int constant_test_bit(int nr, const volatile void * addr)
-{
- return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
-}
-
-static __inline__ int variable_test_bit(int nr, volatile const void * addr)
-{
- int oldbit;
-
- __asm__ __volatile__(
- "btl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit)
- :"m" (ADDR),"dIr" (nr));
- return oldbit;
-}
-
-#define test_bit(nr,addr) \
-(__builtin_constant_p(nr) ? \
- constant_test_bit((nr),(addr)) : \
- variable_test_bit((nr),(addr)))
-
-
-/**
- * set_bit - Atomically set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This function is atomic and may not be reordered. See __set_bit()
- * if you do not require the atomic guarantees.
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static __inline__ void set_bit(int nr, volatile void * addr)
-{
- __asm__ __volatile__( LOCK_PREFIX
- "btsl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr) : "memory");
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * clear_bit() is atomic and may not be reordered. However, it does
- * not contain a memory barrier, so if it is used for locking purposes,
- * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
- * in order to ensure changes are visible on other processors.
- */
-static __inline__ void clear_bit(int nr, volatile void * addr)
-{
- __asm__ __volatile__( LOCK_PREFIX
- "btrl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
-}
-
-/**
- * __ffs - find first bit in word.
- * @word: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static __inline__ unsigned long __ffs(unsigned long word)
-{
- __asm__("bsfq %1,%0"
- :"=r" (word)
- :"rm" (word));
- return word;
-}
-
-#define ADDR (*(volatile long *) addr)
-
-#define rdtscll(val) do { \
- unsigned int __a,__d; \
- asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
- (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
-} while(0)
-
-#define wrmsr(msr,val1,val2) \
- __asm__ __volatile__("wrmsr" \
- : /* no outputs */ \
- : "c" (msr), "a" (val1), "d" (val2))
-
-#define wrmsrl(msr,val) wrmsr(msr,(uint32_t)((uint64_t)(val)),((uint64_t)(val))>>32)
-
-
-#else /* ifdef __x86_64__ */
-#error "Unsupported architecture"
-#endif
-#endif /* ifdef __INSIDE_MINIOS */
-
-/********************* common i386 and x86_64 ****************************/
-struct __synch_xchg_dummy { unsigned long a[100]; };
-#define __synch_xg(x) ((struct __synch_xchg_dummy *)(x))
-
-#define synch_cmpxchg(ptr, old, new) \
-((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
- (unsigned long)(old), \
- (unsigned long)(new), \
- sizeof(*(ptr))))
-
-static inline unsigned long __synch_cmpxchg(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__("lock; cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__synch_xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__("lock; cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__synch_xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
-#ifdef __x86_64__
- case 4:
- __asm__ __volatile__("lock; cmpxchgl %k1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__synch_xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
- case 8:
- __asm__ __volatile__("lock; cmpxchgq %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__synch_xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
-#else
- case 4:
- __asm__ __volatile__("lock; cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__synch_xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
-#endif
- }
- return old;
-}
-
-
-static __inline__ void synch_set_bit(int nr, volatile void * addr)
-{
- __asm__ __volatile__ (
- "lock btsl %1,%0"
- : "=m" (ADDR) : "Ir" (nr) : "memory" );
-}
-
-static __inline__ void synch_clear_bit(int nr, volatile void * addr)
-{
- __asm__ __volatile__ (
- "lock btrl %1,%0"
- : "=m" (ADDR) : "Ir" (nr) : "memory" );
-}
-
-static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
-{
- int oldbit;
- __asm__ __volatile__ (
- "lock btsl %2,%1\n\tsbbl %0,%0"
- : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
- return oldbit;
-}
-
-static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
-{
- int oldbit;
- __asm__ __volatile__ (
- "lock btrl %2,%1\n\tsbbl %0,%0"
- : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
- return oldbit;
-}
-
-static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
-{
- return ((1UL << (nr & 31)) &
- (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
-}
-
-static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
-{
- int oldbit;
- __asm__ __volatile__ (
- "btl %2,%1\n\tsbbl %0,%0"
- : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) );
- return oldbit;
-}
-
-#define synch_test_bit(nr,addr) \
-(__builtin_constant_p(nr) ? \
- synch_const_test_bit((nr),(addr)) : \
- synch_var_test_bit((nr),(addr)))
-
-static inline int
-HYPERVISOR_xsm_op(
- struct xen_flask_op *op)
-{
- return _hypercall1(int, xsm_op, op);
-}
-
-#undef ADDR
-
-#endif /* not assembly */
-#endif /* _OS_H_ */
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Reseach Cambridge
- ****************************************************************************
- *
- * File: traps.h
- * Author: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: Jun 2005
- *
- * Environment: Xen Minimal OS
- * Description: Deals with traps
- *
- ****************************************************************************
- */
-
-#ifndef _TRAPS_H_
-#define _TRAPS_H_
-
-#ifdef __i386__
-struct pt_regs {
- long ebx;
- long ecx;
- long edx;
- long esi;
- long edi;
- long ebp;
- long eax;
- int xds;
- int xes;
- long orig_eax;
- long eip;
- int xcs;
- long eflags;
- long esp;
- int xss;
-};
-#elif __x86_64__
-
-struct pt_regs {
- unsigned long r15;
- unsigned long r14;
- unsigned long r13;
- unsigned long r12;
- unsigned long rbp;
- unsigned long rbx;
-/* arguments: non interrupts/non tracing syscalls only save upto here*/
- unsigned long r11;
- unsigned long r10;
- unsigned long r9;
- unsigned long r8;
- unsigned long rax;
- unsigned long rcx;
- unsigned long rdx;
- unsigned long rsi;
- unsigned long rdi;
- unsigned long orig_rax;
-/* end of arguments */
-/* cpu exception frame or undefined */
- unsigned long rip;
- unsigned long cs;
- unsigned long eflags;
- unsigned long rsp;
- unsigned long ss;
-/* top of stack page */
-};
-
-
-#endif
-
-void dump_regs(struct pt_regs *regs);
-void stack_walk(void);
-
-#define TRAP_PF_PROT 0x1
-#define TRAP_PF_WRITE 0x2
-#define TRAP_PF_USER 0x4
-
-#endif /* _TRAPS_H_ */
+++ /dev/null
-#define __WORDSIZE 32
+++ /dev/null
-/******************************************************************************
- * hypercall-x86_32.h
- *
- * Copied from XenLinux.
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef __HYPERCALL_X86_32_H__
-#define __HYPERCALL_X86_32_H__
-
-#include <xen/xen.h>
-#include <xen/sched.h>
-#include <xen/nmi.h>
-#include <mini-os/mm.h>
-
-typedef struct { unsigned long pte_low, pte_high; } pte_t;
-
-#define __pte(x) ({ unsigned long long _x = (x); \
- ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-extern char hypercall_page[PAGE_SIZE];
-
-#define _hypercall0(type, name) \
-({ \
- long __res; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res) \
- : \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall1(type, name, a1) \
-({ \
- long __res, __ign1; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=b" (__ign1) \
- : "1" ((long)(a1)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall2(type, name, a1, a2) \
-({ \
- long __res, __ign1, __ign2; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
- : "1" ((long)(a1)), "2" ((long)(a2)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall3(type, name, a1, a2, a3) \
-({ \
- long __res, __ign1, __ign2, __ign3; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall4(type, name, a1, a2, a3, a4) \
-({ \
- long __res, __ign1, __ign2, __ign3, __ign4; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3), "=S" (__ign4) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "4" ((long)(a4)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
-({ \
- long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "4" ((long)(a4)), \
- "5" ((long)(a5)) \
- : "memory" ); \
- (type)__res; \
-})
-
-static inline int
-HYPERVISOR_set_trap_table(
- trap_info_t *table)
-{
- return _hypercall1(int, set_trap_table, table);
-}
-
-static inline int
-HYPERVISOR_mmu_update(
- mmu_update_t *req, int count, int *success_count, domid_t domid)
-{
- return _hypercall4(int, mmu_update, req, count, success_count, domid);
-}
-
-static inline int
-HYPERVISOR_mmuext_op(
- struct mmuext_op *op, int count, int *success_count, domid_t domid)
-{
- return _hypercall4(int, mmuext_op, op, count, success_count, domid);
-}
-
-static inline int
-HYPERVISOR_set_gdt(
- unsigned long *frame_list, int entries)
-{
- return _hypercall2(int, set_gdt, frame_list, entries);
-}
-
-static inline int
-HYPERVISOR_stack_switch(
- unsigned long ss, unsigned long esp)
-{
- return _hypercall2(int, stack_switch, ss, esp);
-}
-
-static inline int
-HYPERVISOR_set_callbacks(
- unsigned long event_selector, unsigned long event_address,
- unsigned long failsafe_selector, unsigned long failsafe_address)
-{
- return _hypercall4(int, set_callbacks,
- event_selector, event_address,
- failsafe_selector, failsafe_address);
-}
-
-static inline int
-HYPERVISOR_fpu_taskswitch(
- int set)
-{
- return _hypercall1(int, fpu_taskswitch, set);
-}
-
-static inline int
-HYPERVISOR_sched_op(
- int cmd, void *arg)
-{
- return _hypercall2(int, sched_op, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_shutdown(
- unsigned int reason)
-{
- struct sched_shutdown shutdown = { .reason = reason };
- return _hypercall2(int, sched_op, SCHEDOP_shutdown, &shutdown);
-}
-
-static inline long
-HYPERVISOR_set_timer_op(
- uint64_t timeout)
-{
- unsigned long timeout_hi = (unsigned long)(timeout>>32);
- unsigned long timeout_lo = (unsigned long)timeout;
- return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
-}
-
-static inline int
-HYPERVISOR_set_debugreg(
- int reg, unsigned long value)
-{
- return _hypercall2(int, set_debugreg, reg, value);
-}
-
-static inline unsigned long
-HYPERVISOR_get_debugreg(
- int reg)
-{
- return _hypercall1(unsigned long, get_debugreg, reg);
-}
-
-static inline int
-HYPERVISOR_update_descriptor(
- uint64_t ma, uint64_t desc)
-{
- return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
-}
-
-static inline int
-HYPERVISOR_memory_op(
- unsigned int cmd, void *arg)
-{
- return _hypercall2(int, memory_op, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_multicall(
- void *call_list, int nr_calls)
-{
- return _hypercall2(int, multicall, call_list, nr_calls);
-}
-
-static inline int
-HYPERVISOR_update_va_mapping(
- unsigned long va, pte_t new_val, unsigned long flags)
-{
- return _hypercall4(int, update_va_mapping, va,
- new_val.pte_low, new_val.pte_high, flags);
-}
-
-static inline int
-HYPERVISOR_event_channel_op(
- int cmd, void *op)
-{
- return _hypercall2(int, event_channel_op, cmd, op);
-}
-
-static inline int
-HYPERVISOR_xen_version(
- int cmd, void *arg)
-{
- return _hypercall2(int, xen_version, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_console_io(
- int cmd, int count, char *str)
-{
- return _hypercall3(int, console_io, cmd, count, str);
-}
-
-static inline int
-HYPERVISOR_physdev_op(
- int cmd, void *physdev_op)
-{
- return _hypercall2(int, physdev_op, cmd, physdev_op);
-}
-
-static inline int
-HYPERVISOR_grant_table_op(
- unsigned int cmd, void *uop, unsigned int count)
-{
- return _hypercall3(int, grant_table_op, cmd, uop, count);
-}
-
-static inline int
-HYPERVISOR_update_va_mapping_otherdomain(
- unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
-{
- return _hypercall5(int, update_va_mapping_otherdomain, va,
- new_val.pte_low, new_val.pte_high, flags, domid);
-}
-
-static inline int
-HYPERVISOR_vm_assist(
- unsigned int cmd, unsigned int type)
-{
- return _hypercall2(int, vm_assist, cmd, type);
-}
-
-static inline int
-HYPERVISOR_vcpu_op(
- int cmd, int vcpuid, void *extra_args)
-{
- return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
-}
-
-static inline int
-HYPERVISOR_suspend(
- unsigned long srec)
-{
- return _hypercall3(int, sched_op, SCHEDOP_shutdown,
- SHUTDOWN_suspend, srec);
-}
-
-static inline int
-HYPERVISOR_nmi_op(
- unsigned long op,
- unsigned long arg)
-{
- return _hypercall2(int, nmi_op, op, arg);
-}
-
-static inline int
-HYPERVISOR_sysctl(
- unsigned long op)
-{
- return _hypercall1(int, sysctl, op);
-}
-
-static inline int
-HYPERVISOR_domctl(
- unsigned long op)
-{
- return _hypercall1(int, domctl, op);
-}
-
-#endif /* __HYPERCALL_X86_32_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
+++ /dev/null
-#define __WORDSIZE 64
-#define __WORDSIZE_COMPAT32 1
+++ /dev/null
-/******************************************************************************
- * hypercall-x86_64.h
- *
- * Copied from XenLinux.
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * 64-bit updates:
- * Benjamin Liu <benjamin.liu@intel.com>
- * Jun Nakajima <jun.nakajima@intel.com>
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef __HYPERCALL_X86_64_H__
-#define __HYPERCALL_X86_64_H__
-
-#include <xen/xen.h>
-#include <xen/sched.h>
-#include <mini-os/mm.h>
-
-typedef struct { unsigned long pte; } pte_t;
-
-#define __pte(x) ((pte_t) { (x) } )
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-extern char hypercall_page[PAGE_SIZE];
-
-#define _hypercall0(type, name) \
-({ \
- long __res; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res) \
- : \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall1(type, name, a1) \
-({ \
- long __res, __ign1; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=D" (__ign1) \
- : "1" ((long)(a1)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall2(type, name, a1, a2) \
-({ \
- long __res, __ign1, __ign2; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \
- : "1" ((long)(a1)), "2" ((long)(a2)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall3(type, name, a1, a2, a3) \
-({ \
- long __res, __ign1, __ign2, __ign3; \
- asm volatile ( \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
- "=d" (__ign3) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)) \
- : "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall4(type, name, a1, a2, a3, a4) \
-({ \
- long __res, __ign1, __ign2, __ign3; \
- asm volatile ( \
- "movq %7,%%r10; " \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
- "=d" (__ign3) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "g" ((long)(a4)) \
- : "memory", "r10" ); \
- (type)__res; \
-})
-
-#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
-({ \
- long __res, __ign1, __ign2, __ign3; \
- asm volatile ( \
- "movq %7,%%r10; movq %8,%%r8; " \
- "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
- : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
- "=d" (__ign3) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "g" ((long)(a4)), \
- "g" ((long)(a5)) \
- : "memory", "r10", "r8" ); \
- (type)__res; \
-})
-
-static inline int
-HYPERVISOR_set_trap_table(
- trap_info_t *table)
-{
- return _hypercall1(int, set_trap_table, table);
-}
-
-static inline int
-HYPERVISOR_mmu_update(
- mmu_update_t *req, int count, int *success_count, domid_t domid)
-{
- return _hypercall4(int, mmu_update, req, count, success_count, domid);
-}
-
-static inline int
-HYPERVISOR_mmuext_op(
- struct mmuext_op *op, int count, int *success_count, domid_t domid)
-{
- return _hypercall4(int, mmuext_op, op, count, success_count, domid);
-}
-
-static inline int
-HYPERVISOR_set_gdt(
- unsigned long *frame_list, int entries)
-{
- return _hypercall2(int, set_gdt, frame_list, entries);
-}
-
-static inline int
-HYPERVISOR_stack_switch(
- unsigned long ss, unsigned long esp)
-{
- return _hypercall2(int, stack_switch, ss, esp);
-}
-
-static inline int
-HYPERVISOR_set_callbacks(
- unsigned long event_address, unsigned long failsafe_address,
- unsigned long syscall_address)
-{
- return _hypercall3(int, set_callbacks,
- event_address, failsafe_address, syscall_address);
-}
-
-static inline int
-HYPERVISOR_fpu_taskswitch(
- int set)
-{
- return _hypercall1(int, fpu_taskswitch, set);
-}
-
-static inline int
-HYPERVISOR_sched_op(
- int cmd, void *arg)
-{
- return _hypercall2(int, sched_op, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_shutdown(
- unsigned int reason)
-{
- struct sched_shutdown shutdown = { .reason = reason };
- return _hypercall2(int, sched_op, SCHEDOP_shutdown, &shutdown);
-}
-
-static inline long
-HYPERVISOR_set_timer_op(
- uint64_t timeout)
-{
- return _hypercall1(long, set_timer_op, timeout);
-}
-
-static inline int
-HYPERVISOR_set_debugreg(
- int reg, unsigned long value)
-{
- return _hypercall2(int, set_debugreg, reg, value);
-}
-
-static inline unsigned long
-HYPERVISOR_get_debugreg(
- int reg)
-{
- return _hypercall1(unsigned long, get_debugreg, reg);
-}
-
-static inline int
-HYPERVISOR_update_descriptor(
- unsigned long ma, unsigned long word)
-{
- return _hypercall2(int, update_descriptor, ma, word);
-}
-
-static inline int
-HYPERVISOR_memory_op(
- unsigned int cmd, void *arg)
-{
- return _hypercall2(int, memory_op, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_multicall(
- void *call_list, int nr_calls)
-{
- return _hypercall2(int, multicall, call_list, nr_calls);
-}
-
-static inline int
-HYPERVISOR_update_va_mapping(
- unsigned long va, pte_t new_val, unsigned long flags)
-{
- return _hypercall3(int, update_va_mapping, va, new_val.pte, flags);
-}
-
-static inline int
-HYPERVISOR_event_channel_op(
- int cmd, void *op)
-{
- return _hypercall2(int, event_channel_op, cmd, op);
-}
-
-static inline int
-HYPERVISOR_xen_version(
- int cmd, void *arg)
-{
- return _hypercall2(int, xen_version, cmd, arg);
-}
-
-static inline int
-HYPERVISOR_console_io(
- int cmd, int count, char *str)
-{
- return _hypercall3(int, console_io, cmd, count, str);
-}
-
-static inline int
-HYPERVISOR_physdev_op(
- int cmd, void *physdev_op)
-{
- return _hypercall2(int, physdev_op, cmd, physdev_op);
-}
-
-static inline int
-HYPERVISOR_grant_table_op(
- unsigned int cmd, void *uop, unsigned int count)
-{
- return _hypercall3(int, grant_table_op, cmd, uop, count);
-}
-
-static inline int
-HYPERVISOR_update_va_mapping_otherdomain(
- unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
-{
- return _hypercall4(int, update_va_mapping_otherdomain, va,
- new_val.pte, flags, domid);
-}
-
-static inline int
-HYPERVISOR_vm_assist(
- unsigned int cmd, unsigned int type)
-{
- return _hypercall2(int, vm_assist, cmd, type);
-}
-
-static inline int
-HYPERVISOR_vcpu_op(
- int cmd, int vcpuid, void *extra_args)
-{
- return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
-}
-
-static inline int
-HYPERVISOR_set_segment_base(
- int reg, unsigned long value)
-{
- return _hypercall2(int, set_segment_base, reg, value);
-}
-
-static inline int
-HYPERVISOR_suspend(
- unsigned long srec)
-{
- return _hypercall3(int, sched_op, SCHEDOP_shutdown,
- SHUTDOWN_suspend, srec);
-}
-
-static inline int
-HYPERVISOR_nmi_op(
- unsigned long op,
- unsigned long arg)
-{
- return _hypercall2(int, nmi_op, op, arg);
-}
-
-static inline int
-HYPERVISOR_sysctl(
- unsigned long op)
-{
- return _hypercall1(int, sysctl, op);
-}
-
-static inline int
-HYPERVISOR_domctl(
- unsigned long op)
-{
- return _hypercall1(int, domctl, op);
-}
-
-#endif /* __HYPERCALL_X86_64_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
+++ /dev/null
-XEN NOTICE
-==========
-
-This copyright applies to all files within this subdirectory and its
-subdirectories:
- include/public/*.h
- include/public/hvm/*.h
- include/public/io/*.h
-
-The intention is that these files can be freely copied into the source
-tree of an operating system when porting that OS to run on Xen. Doing
-so does *not* cause the OS to become subject to the terms of the GPL.
-
-All other files in the Xen source distribution are covered by version
-2 of the GNU General Public License except where explicitly stated
-otherwise within individual source files.
-
- -- Keir Fraser (on behalf of the Xen team)
-
-=====================================================================
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+++ /dev/null
-/******************************************************************************
- * arch-arm.h
- *
- * Guest OS interface to ARM Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright 2011 (C) Citrix Systems
- */
-
-#ifndef __XEN_PUBLIC_ARCH_ARM_H__
-#define __XEN_PUBLIC_ARCH_ARM_H__
-
-/*
- * `incontents 50 arm_abi Hypercall Calling Convention
- *
- * A hypercall is issued using the ARM HVC instruction.
- *
- * A hypercall can take up to 5 arguments. These are passed in
- * registers, the first argument in x0/r0 (for arm64/arm32 guests
- * respectively irrespective of whether the underlying hypervisor is
- * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
- * the forth in x3/r3 and the fifth in x4/r4.
- *
- * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
- * cases the relevant ARM procedure calling convention specifies this
- * is an inter-procedure-call scratch register (e.g. for use in linker
- * stubs). This use does not conflict with use during a hypercall.
- *
- * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
- *
- * The return value is in x0/r0.
- *
- * The hypercall will clobber x16/r12 and the argument registers used
- * by that hypercall (except r0 which is the return value) i.e. in
- * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
- * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
- *
- * Parameter structs passed to hypercalls are laid out according to
- * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
- * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
- * (AAPCS64). Where there is a conflict the 64-bit standard should be
- * used regardless of guest type. Structures which are passed as
- * hypercall arguments are always little endian.
- *
- * All memory which is shared with other entities in the system
- * (including the hypervisor and other guests) must reside in memory
- * which is mapped as Normal Inner-cacheable. This applies to:
- * - hypercall arguments passed via a pointer to guest memory.
- * - memory shared via the grant table mechanism (including PV I/O
- * rings etc).
- * - memory shared with the hypervisor (struct shared_info, struct
- * vcpu_info, the grant table, etc).
- *
- * Any Inner cache allocation strategy (Write-Back, Write-Through etc)
- * is acceptable. There is no restriction on the Outer-cacheability.
- */
-
-/*
- * `incontents 55 arm_hcall Supported Hypercalls
- *
- * Xen on ARM makes extensive use of hardware facilities and therefore
- * only a subset of the potential hypercalls are required.
- *
- * Since ARM uses second stage paging any machine/physical addresses
- * passed to hypercalls are Guest Physical Addresses (Intermediate
- * Physical Addresses) unless otherwise noted.
- *
- * The following hypercalls (and sub operations) are supported on the
- * ARM platform. Other hypercalls should be considered
- * unavailable/unsupported.
- *
- * HYPERVISOR_memory_op
- * All generic sub-operations
- *
- * HYPERVISOR_domctl
- * All generic sub-operations, with the exception of:
- * * XEN_DOMCTL_irq_permission (not yet implemented)
- *
- * HYPERVISOR_sched_op
- * All generic sub-operations, with the exception of:
- * * SCHEDOP_block -- prefer wfi hardware instruction
- *
- * HYPERVISOR_console_io
- * All generic sub-operations
- *
- * HYPERVISOR_xen_version
- * All generic sub-operations
- *
- * HYPERVISOR_event_channel_op
- * All generic sub-operations
- *
- * HYPERVISOR_physdev_op
- * No sub-operations are currenty supported
- *
- * HYPERVISOR_sysctl
- * All generic sub-operations, with the exception of:
- * * XEN_SYSCTL_page_offline_op
- * * XEN_SYSCTL_get_pmstat
- * * XEN_SYSCTL_pm_op
- *
- * HYPERVISOR_hvm_op
- * Exactly these sub-operations are supported:
- * * HVMOP_set_param
- * * HVMOP_get_param
- *
- * HYPERVISOR_grant_table_op
- * All generic sub-operations
- *
- * HYPERVISOR_vcpu_op
- * Exactly these sub-operations are supported:
- * * VCPUOP_register_vcpu_info
- * * VCPUOP_register_runstate_memory_area
- *
- *
- * Other notes on the ARM ABI:
- *
- * - struct start_info is not exported to ARM guests.
- *
- * - struct shared_info is mapped by ARM guests using the
- * HYPERVISOR_memory_op sub-op XENMEM_add_to_physmap, passing
- * XENMAPSPACE_shared_info as space parameter.
- *
- * - All the per-cpu struct vcpu_info are mapped by ARM guests using the
- * HYPERVISOR_vcpu_op sub-op VCPUOP_register_vcpu_info, including cpu0
- * struct vcpu_info.
- *
- * - The grant table is mapped using the HYPERVISOR_memory_op sub-op
- * XENMEM_add_to_physmap, passing XENMAPSPACE_grant_table as space
- * parameter. The memory range specified under the Xen compatible
- * hypervisor node on device tree can be used as target gpfn for the
- * mapping.
- *
- * - Xenstore is initialized by using the two hvm_params
- * HVM_PARAM_STORE_PFN and HVM_PARAM_STORE_EVTCHN. They can be read
- * with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
- *
- * - The paravirtualized console is initialized by using the two
- * hvm_params HVM_PARAM_CONSOLE_PFN and HVM_PARAM_CONSOLE_EVTCHN. They
- * can be read with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
- *
- * - Event channel notifications are delivered using the percpu GIC
- * interrupt specified under the Xen compatible hypervisor node on
- * device tree.
- *
- * - The device tree Xen compatible node is fully described under Linux
- * at Documentation/devicetree/bindings/arm/xen.txt.
- */
-
-#define XEN_HYPERCALL_TAG 0XEA1
-
-#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-
-#ifndef __ASSEMBLY__
-#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
- typedef union { type *p; unsigned long q; } \
- __guest_handle_ ## name; \
- typedef union { type *p; uint64_aligned_t q; } \
- __guest_handle_64_ ## name;
-
-/*
- * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
- * in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes
- * aligned.
- * XEN_GUEST_HANDLE_PARAM represents a guest pointer, when passed as an
- * hypercall argument. It is 4 bytes on aarch32 and 8 bytes on aarch64.
- */
-#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
- ___DEFINE_XEN_GUEST_HANDLE(name, type); \
- ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
-#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
-#define __XEN_GUEST_HANDLE(name) __guest_handle_64_ ## name
-#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
-#define XEN_GUEST_HANDLE_PARAM(name) __guest_handle_ ## name
-#define set_xen_guest_handle_raw(hnd, val) \
- do { \
- typeof(&(hnd)) _sxghr_tmp = &(hnd); \
- _sxghr_tmp->q = 0; \
- _sxghr_tmp->p = val; \
- } while ( 0 )
-#ifdef __XEN_TOOLS__
-#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
-#endif
-#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
-# define __DECL_REG(n64, n32) union { \
- uint64_t n64; \
- uint32_t n32; \
- }
-#else
-/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */
-#define __DECL_REG(n64, n32) uint64_t n64
-#endif
-
-struct vcpu_guest_core_regs
-{
- /* Aarch64 Aarch32 */
- __DECL_REG(x0, r0_usr);
- __DECL_REG(x1, r1_usr);
- __DECL_REG(x2, r2_usr);
- __DECL_REG(x3, r3_usr);
- __DECL_REG(x4, r4_usr);
- __DECL_REG(x5, r5_usr);
- __DECL_REG(x6, r6_usr);
- __DECL_REG(x7, r7_usr);
- __DECL_REG(x8, r8_usr);
- __DECL_REG(x9, r9_usr);
- __DECL_REG(x10, r10_usr);
- __DECL_REG(x11, r11_usr);
- __DECL_REG(x12, r12_usr);
-
- __DECL_REG(x13, sp_usr);
- __DECL_REG(x14, lr_usr);
-
- __DECL_REG(x15, __unused_sp_hyp);
-
- __DECL_REG(x16, lr_irq);
- __DECL_REG(x17, sp_irq);
-
- __DECL_REG(x18, lr_svc);
- __DECL_REG(x19, sp_svc);
-
- __DECL_REG(x20, lr_abt);
- __DECL_REG(x21, sp_abt);
-
- __DECL_REG(x22, lr_und);
- __DECL_REG(x23, sp_und);
-
- __DECL_REG(x24, r8_fiq);
- __DECL_REG(x25, r9_fiq);
- __DECL_REG(x26, r10_fiq);
- __DECL_REG(x27, r11_fiq);
- __DECL_REG(x28, r12_fiq);
-
- __DECL_REG(x29, sp_fiq);
- __DECL_REG(x30, lr_fiq);
-
- /* Return address and mode */
- __DECL_REG(pc64, pc32); /* ELR_EL2 */
- uint32_t cpsr; /* SPSR_EL2 */
-
- union {
- uint32_t spsr_el1; /* AArch64 */
- uint32_t spsr_svc; /* AArch32 */
- };
-
- /* AArch32 guests only */
- uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
-
- /* AArch64 guests only */
- uint64_t sp_el0;
- uint64_t sp_el1, elr_el1;
-};
-typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
-
-#undef __DECL_REG
-
-typedef uint64_t xen_pfn_t;
-#define PRI_xen_pfn PRIx64
-
-/* Maximum number of virtual CPUs in legacy multi-processor guests. */
-/* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */
-#define XEN_LEGACY_MAX_VCPUS 1
-
-typedef uint64_t xen_ulong_t;
-#define PRI_xen_ulong PRIx64
-
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-struct vcpu_guest_context {
-#define _VGCF_online 0
-#define VGCF_online (1<<_VGCF_online)
- uint32_t flags; /* VGCF_* */
-
- struct vcpu_guest_core_regs user_regs; /* Core CPU registers */
-
- uint32_t sctlr;
- uint64_t ttbcr, ttbr0, ttbr1;
-};
-typedef struct vcpu_guest_context vcpu_guest_context_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-#endif
-
-struct arch_vcpu_info {
-};
-typedef struct arch_vcpu_info arch_vcpu_info_t;
-
-struct arch_shared_info {
-};
-typedef struct arch_shared_info arch_shared_info_t;
-typedef uint64_t xen_callback_t;
-
-#endif
-
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-/* PSR bits (CPSR, SPSR) */
-
-#define PSR_THUMB (1<<5) /* Thumb Mode enable */
-#define PSR_FIQ_MASK (1<<6) /* Fast Interrupt mask */
-#define PSR_IRQ_MASK (1<<7) /* Interrupt mask */
-#define PSR_ABT_MASK (1<<8) /* Asynchronous Abort mask */
-#define PSR_BIG_ENDIAN (1<<9) /* arm32: Big Endian Mode */
-#define PSR_DBG_MASK (1<<9) /* arm64: Debug Exception mask */
-#define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */
-#define PSR_JAZELLE (1<<24) /* Jazelle Mode */
-
-/* 32 bit modes */
-#define PSR_MODE_USR 0x10
-#define PSR_MODE_FIQ 0x11
-#define PSR_MODE_IRQ 0x12
-#define PSR_MODE_SVC 0x13
-#define PSR_MODE_MON 0x16
-#define PSR_MODE_ABT 0x17
-#define PSR_MODE_HYP 0x1a
-#define PSR_MODE_UND 0x1b
-#define PSR_MODE_SYS 0x1f
-
-/* 64 bit modes */
-#define PSR_MODE_BIT 0x10 /* Set iff AArch32 */
-#define PSR_MODE_EL3h 0x0d
-#define PSR_MODE_EL3t 0x0c
-#define PSR_MODE_EL2h 0x09
-#define PSR_MODE_EL2t 0x08
-#define PSR_MODE_EL1h 0x05
-#define PSR_MODE_EL1t 0x04
-#define PSR_MODE_EL0t 0x00
-
-#define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
-#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
-
-#define SCTLR_GUEST_INIT 0x00c50078
-
-/*
- * Virtual machine platform (memory layout, interrupts)
- *
- * These are defined for consistency between the tools and the
- * hypervisor. Guests must not rely on these hardcoded values but
- * should instead use the FDT.
- */
-
-/* Physical Address Space */
-
-/*
- * vGIC mappings: Only one set of mapping is used by the guest.
- * Therefore they can overlap.
- */
-
-/* vGIC v2 mappings */
-#define GUEST_GICD_BASE 0x03001000ULL
-#define GUEST_GICD_SIZE 0x00001000ULL
-#define GUEST_GICC_BASE 0x03002000ULL
-#define GUEST_GICC_SIZE 0x00000100ULL
-
-/* vGIC v3 mappings */
-#define GUEST_GICV3_GICD_BASE 0x03001000ULL
-#define GUEST_GICV3_GICD_SIZE 0x00010000ULL
-
-#define GUEST_GICV3_RDIST_STRIDE 0x20000ULL
-#define GUEST_GICV3_RDIST_REGIONS 1
-
-#define GUEST_GICV3_GICR0_BASE 0x03020000ULL /* vCPU0 - vCPU7 */
-#define GUEST_GICV3_GICR0_SIZE 0x00100000ULL
-
-/*
- * 16MB == 4096 pages reserved for guest to use as a region to map its
- * grant table in.
- */
-#define GUEST_GNTTAB_BASE 0x38000000ULL
-#define GUEST_GNTTAB_SIZE 0x01000000ULL
-
-#define GUEST_MAGIC_BASE 0x39000000ULL
-#define GUEST_MAGIC_SIZE 0x01000000ULL
-
-#define GUEST_RAM_BANKS 2
-
-#define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */
-#define GUEST_RAM0_SIZE 0xc0000000ULL
-
-#define GUEST_RAM1_BASE 0x0200000000ULL /* 1016GB of RAM @ 8GB */
-#define GUEST_RAM1_SIZE 0xfe00000000ULL
-
-#define GUEST_RAM_BASE GUEST_RAM0_BASE /* Lowest RAM address */
-/* Largest amount of actual RAM, not including holes */
-#define GUEST_RAM_MAX (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE)
-/* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */
-#define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE }
-#define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }
-
-/* Interrupts */
-#define GUEST_TIMER_VIRT_PPI 27
-#define GUEST_TIMER_PHYS_S_PPI 29
-#define GUEST_TIMER_PHYS_NS_PPI 30
-#define GUEST_EVTCHN_PPI 31
-
-/* PSCI functions */
-#define PSCI_cpu_suspend 0
-#define PSCI_cpu_off 1
-#define PSCI_cpu_on 2
-#define PSCI_migrate 3
-
-#endif
-
-#endif /* __XEN_PUBLIC_ARCH_ARM_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Structure definitions for HVM state that is held by Xen and must
- * be saved along with the domain's memory and device-model state.
- *
- * Copyright (c) 2012 Citrix Systems Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_SAVE_ARM_H__
-#define __XEN_PUBLIC_HVM_SAVE_ARM_H__
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * arch-x86/cpuid.h
- *
- * CPUID interface to Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2007 Citrix Systems, Inc.
- *
- * Authors:
- * Keir Fraser <keir@xen.org>
- */
-
-#ifndef __XEN_PUBLIC_ARCH_X86_CPUID_H__
-#define __XEN_PUBLIC_ARCH_X86_CPUID_H__
-
-/*
- * For compatibility with other hypervisor interfaces, the Xen cpuid leaves
- * can be found at the first otherwise unused 0x100 aligned boundary starting
- * from 0x40000000.
- *
- * e.g If viridian extensions are enabled for an HVM domain, the Xen cpuid
- * leaves will start at 0x40000100
- */
-
-#define XEN_CPUID_FIRST_LEAF 0x40000000
-#define XEN_CPUID_LEAF(i) (XEN_CPUID_FIRST_LEAF + (i))
-
-/*
- * Leaf 1 (0x40000x00)
- * EAX: Largest Xen-information leaf. All leaves up to an including @EAX
- * are supported by the Xen host.
- * EBX-EDX: "XenVMMXenVMM" signature, allowing positive identification
- * of a Xen host.
- */
-#define XEN_CPUID_SIGNATURE_EBX 0x566e6558 /* "XenV" */
-#define XEN_CPUID_SIGNATURE_ECX 0x65584d4d /* "MMXe" */
-#define XEN_CPUID_SIGNATURE_EDX 0x4d4d566e /* "nVMM" */
-
-/*
- * Leaf 2 (0x40000x01)
- * EAX[31:16]: Xen major version.
- * EAX[15: 0]: Xen minor version.
- * EBX-EDX: Reserved (currently all zeroes).
- */
-
-/*
- * Leaf 3 (0x40000x02)
- * EAX: Number of hypercall transfer pages. This register is always guaranteed
- * to specify one hypercall page.
- * EBX: Base address of Xen-specific MSRs.
- * ECX: Features 1. Unused bits are set to zero.
- * EDX: Features 2. Unused bits are set to zero.
- */
-
-/* Does the host support MMU_PT_UPDATE_PRESERVE_AD for this guest? */
-#define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0
-#define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0)
-
-/*
- * Leaf 5 (0x40000x04)
- * HVM-specific features
- * EAX: Features
- * EBX: vcpu id (iff EAX has XEN_HVM_CPUID_VCPU_ID_PRESENT flag)
- */
-#define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0) /* Virtualized APIC registers */
-#define XEN_HVM_CPUID_X2APIC_VIRT (1u << 1) /* Virtualized x2APIC accesses */
-/* Memory mapped from other domains has valid IOMMU entries */
-#define XEN_HVM_CPUID_IOMMU_MAPPINGS (1u << 2)
-#define XEN_HVM_CPUID_VCPU_ID_PRESENT (1u << 3) /* vcpu id is present in EBX */
-
-#define XEN_CPUID_MAX_NUM_LEAVES 4
-
-#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */
+++ /dev/null
-/*
- * Structure definitions for HVM state that is held by Xen and must
- * be saved along with the domain's memory and device-model state.
- *
- * Copyright (c) 2007 XenSource Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__
-#define __XEN_PUBLIC_HVM_SAVE_X86_H__
-
-/*
- * Save/restore header: general info about the save file.
- */
-
-#define HVM_FILE_MAGIC 0x54381286
-#define HVM_FILE_VERSION 0x00000001
-
-struct hvm_save_header {
- uint32_t magic; /* Must be HVM_FILE_MAGIC */
- uint32_t version; /* File format version */
- uint64_t changeset; /* Version of Xen that saved this file */
- uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */
- uint32_t gtsc_khz; /* Guest's TSC frequency in kHz */
-};
-
-DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
-
-
-/*
- * Processor
- *
- * Compat: Pre-3.4 didn't have msr_tsc_aux
- */
-
-struct hvm_hw_cpu {
- uint8_t fpu_regs[512];
-
- uint64_t rax;
- uint64_t rbx;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rbp;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t rsp;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
-
- uint64_t rip;
- uint64_t rflags;
-
- uint64_t cr0;
- uint64_t cr2;
- uint64_t cr3;
- uint64_t cr4;
-
- uint64_t dr0;
- uint64_t dr1;
- uint64_t dr2;
- uint64_t dr3;
- uint64_t dr6;
- uint64_t dr7;
-
- uint32_t cs_sel;
- uint32_t ds_sel;
- uint32_t es_sel;
- uint32_t fs_sel;
- uint32_t gs_sel;
- uint32_t ss_sel;
- uint32_t tr_sel;
- uint32_t ldtr_sel;
-
- uint32_t cs_limit;
- uint32_t ds_limit;
- uint32_t es_limit;
- uint32_t fs_limit;
- uint32_t gs_limit;
- uint32_t ss_limit;
- uint32_t tr_limit;
- uint32_t ldtr_limit;
- uint32_t idtr_limit;
- uint32_t gdtr_limit;
-
- uint64_t cs_base;
- uint64_t ds_base;
- uint64_t es_base;
- uint64_t fs_base;
- uint64_t gs_base;
- uint64_t ss_base;
- uint64_t tr_base;
- uint64_t ldtr_base;
- uint64_t idtr_base;
- uint64_t gdtr_base;
-
- uint32_t cs_arbytes;
- uint32_t ds_arbytes;
- uint32_t es_arbytes;
- uint32_t fs_arbytes;
- uint32_t gs_arbytes;
- uint32_t ss_arbytes;
- uint32_t tr_arbytes;
- uint32_t ldtr_arbytes;
-
- uint64_t sysenter_cs;
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
-
- /* msr for em64t */
- uint64_t shadow_gs;
-
- /* msr content saved/restored. */
- uint64_t msr_flags;
- uint64_t msr_lstar;
- uint64_t msr_star;
- uint64_t msr_cstar;
- uint64_t msr_syscall_mask;
- uint64_t msr_efer;
- uint64_t msr_tsc_aux;
-
- /* guest's idea of what rdtsc() would return */
- uint64_t tsc;
-
- /* pending event, if any */
- union {
- uint32_t pending_event;
- struct {
- uint8_t pending_vector:8;
- uint8_t pending_type:3;
- uint8_t pending_error_valid:1;
- uint32_t pending_reserved:19;
- uint8_t pending_valid:1;
- };
- };
- /* error code for pending event */
- uint32_t error_code;
-};
-
-struct hvm_hw_cpu_compat {
- uint8_t fpu_regs[512];
-
- uint64_t rax;
- uint64_t rbx;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rbp;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t rsp;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
-
- uint64_t rip;
- uint64_t rflags;
-
- uint64_t cr0;
- uint64_t cr2;
- uint64_t cr3;
- uint64_t cr4;
-
- uint64_t dr0;
- uint64_t dr1;
- uint64_t dr2;
- uint64_t dr3;
- uint64_t dr6;
- uint64_t dr7;
-
- uint32_t cs_sel;
- uint32_t ds_sel;
- uint32_t es_sel;
- uint32_t fs_sel;
- uint32_t gs_sel;
- uint32_t ss_sel;
- uint32_t tr_sel;
- uint32_t ldtr_sel;
-
- uint32_t cs_limit;
- uint32_t ds_limit;
- uint32_t es_limit;
- uint32_t fs_limit;
- uint32_t gs_limit;
- uint32_t ss_limit;
- uint32_t tr_limit;
- uint32_t ldtr_limit;
- uint32_t idtr_limit;
- uint32_t gdtr_limit;
-
- uint64_t cs_base;
- uint64_t ds_base;
- uint64_t es_base;
- uint64_t fs_base;
- uint64_t gs_base;
- uint64_t ss_base;
- uint64_t tr_base;
- uint64_t ldtr_base;
- uint64_t idtr_base;
- uint64_t gdtr_base;
-
- uint32_t cs_arbytes;
- uint32_t ds_arbytes;
- uint32_t es_arbytes;
- uint32_t fs_arbytes;
- uint32_t gs_arbytes;
- uint32_t ss_arbytes;
- uint32_t tr_arbytes;
- uint32_t ldtr_arbytes;
-
- uint64_t sysenter_cs;
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
-
- /* msr for em64t */
- uint64_t shadow_gs;
-
- /* msr content saved/restored. */
- uint64_t msr_flags;
- uint64_t msr_lstar;
- uint64_t msr_star;
- uint64_t msr_cstar;
- uint64_t msr_syscall_mask;
- uint64_t msr_efer;
- /*uint64_t msr_tsc_aux; COMPAT */
-
- /* guest's idea of what rdtsc() would return */
- uint64_t tsc;
-
- /* pending event, if any */
- union {
- uint32_t pending_event;
- struct {
- uint8_t pending_vector:8;
- uint8_t pending_type:3;
- uint8_t pending_error_valid:1;
- uint32_t pending_reserved:19;
- uint8_t pending_valid:1;
- };
- };
- /* error code for pending event */
- uint32_t error_code;
-};
-
-static inline int _hvm_hw_fix_cpu(void *h) {
-
- union hvm_hw_cpu_union {
- struct hvm_hw_cpu nat;
- struct hvm_hw_cpu_compat cmp;
- } *ucpu = (union hvm_hw_cpu_union *)h;
-
- /* If we copy from the end backwards, we should
- * be able to do the modification in-place */
- ucpu->nat.error_code = ucpu->cmp.error_code;
- ucpu->nat.pending_event = ucpu->cmp.pending_event;
- ucpu->nat.tsc = ucpu->cmp.tsc;
- ucpu->nat.msr_tsc_aux = 0;
-
- return 0;
-}
-
-DECLARE_HVM_SAVE_TYPE_COMPAT(CPU, 2, struct hvm_hw_cpu, \
- struct hvm_hw_cpu_compat, _hvm_hw_fix_cpu);
-
-/*
- * PIC
- */
-
-struct hvm_hw_vpic {
- /* IR line bitmasks. */
- uint8_t irr;
- uint8_t imr;
- uint8_t isr;
-
- /* Line IRx maps to IRQ irq_base+x */
- uint8_t irq_base;
-
- /*
- * Where are we in ICW2-4 initialisation (0 means no init in progress)?
- * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
- * Bit 2: ICW1.IC4 (1 == ICW4 included in init sequence)
- * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
- */
- uint8_t init_state:4;
-
- /* IR line with highest priority. */
- uint8_t priority_add:4;
-
- /* Reads from A=0 obtain ISR or IRR? */
- uint8_t readsel_isr:1;
-
- /* Reads perform a polling read? */
- uint8_t poll:1;
-
- /* Automatically clear IRQs from the ISR during INTA? */
- uint8_t auto_eoi:1;
-
- /* Automatically rotate IRQ priorities during AEOI? */
- uint8_t rotate_on_auto_eoi:1;
-
- /* Exclude slave inputs when considering in-service IRQs? */
- uint8_t special_fully_nested_mode:1;
-
- /* Special mask mode excludes masked IRs from AEOI and priority checks. */
- uint8_t special_mask_mode:1;
-
- /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
- uint8_t is_master:1;
-
- /* Edge/trigger selection. */
- uint8_t elcr;
-
- /* Virtual INT output. */
- uint8_t int_output;
-};
-
-DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
-
-
-/*
- * IO-APIC
- */
-
-#define VIOAPIC_NUM_PINS 48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
-
-struct hvm_hw_vioapic {
- uint64_t base_address;
- uint32_t ioregsel;
- uint32_t id;
- union vioapic_redir_entry
- {
- uint64_t bits;
- struct {
- uint8_t vector;
- uint8_t delivery_mode:3;
- uint8_t dest_mode:1;
- uint8_t delivery_status:1;
- uint8_t polarity:1;
- uint8_t remote_irr:1;
- uint8_t trig_mode:1;
- uint8_t mask:1;
- uint8_t reserve:7;
- uint8_t reserved[4];
- uint8_t dest_id;
- } fields;
- } redirtbl[VIOAPIC_NUM_PINS];
-};
-
-DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
-
-
-/*
- * LAPIC
- */
-
-struct hvm_hw_lapic {
- uint64_t apic_base_msr;
- uint32_t disabled; /* VLAPIC_xx_DISABLED */
- uint32_t timer_divisor;
- uint64_t tdt_msr;
-};
-
-DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
-
-struct hvm_hw_lapic_regs {
- uint8_t data[1024];
-};
-
-DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
-
-
-/*
- * IRQs
- */
-
-struct hvm_hw_pci_irqs {
- /*
- * Virtual interrupt wires for a single PCI bus.
- * Indexed by: device*4 + INTx#.
- */
- union {
- unsigned long i[16 / sizeof (unsigned long)]; /* DECLARE_BITMAP(i, 32*4); */
- uint64_t pad[2];
- };
-};
-
-DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);
-
-struct hvm_hw_isa_irqs {
- /*
- * Virtual interrupt wires for ISA devices.
- * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
- */
- union {
- unsigned long i[1]; /* DECLARE_BITMAP(i, 16); */
- uint64_t pad[1];
- };
-};
-
-DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);
-
-struct hvm_hw_pci_link {
- /*
- * PCI-ISA interrupt router.
- * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
- * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
- * The router provides a programmable mapping from each link to a GSI.
- */
- uint8_t route[4];
- uint8_t pad0[4];
-};
-
-DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
-
-/*
- * PIT
- */
-
-struct hvm_hw_pit {
- struct hvm_hw_pit_channel {
- uint32_t count; /* can be 65536 */
- uint16_t latched_count;
- uint8_t count_latched;
- uint8_t status_latched;
- uint8_t status;
- uint8_t read_state;
- uint8_t write_state;
- uint8_t write_latch;
- uint8_t rw_mode;
- uint8_t mode;
- uint8_t bcd; /* not supported */
- uint8_t gate; /* timer start */
- } channels[3]; /* 3 x 16 bytes */
- uint32_t speaker_data_on;
- uint32_t pad0;
-};
-
-DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
-
-
-/*
- * RTC
- */
-
-#define RTC_CMOS_SIZE 14
-struct hvm_hw_rtc {
- /* CMOS bytes */
- uint8_t cmos_data[RTC_CMOS_SIZE];
- /* Index register for 2-part operations */
- uint8_t cmos_index;
- uint8_t pad0;
-};
-
-DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
-
-
-/*
- * HPET
- */
-
-#define HPET_TIMER_NUM 3 /* 3 timers supported now */
-struct hvm_hw_hpet {
- /* Memory-mapped, software visible registers */
- uint64_t capability; /* capabilities */
- uint64_t res0; /* reserved */
- uint64_t config; /* configuration */
- uint64_t res1; /* reserved */
- uint64_t isr; /* interrupt status reg */
- uint64_t res2[25]; /* reserved */
- uint64_t mc64; /* main counter */
- uint64_t res3; /* reserved */
- struct { /* timers */
- uint64_t config; /* configuration/cap */
- uint64_t cmp; /* comparator */
- uint64_t fsb; /* FSB route, not supported now */
- uint64_t res4; /* reserved */
- } timers[HPET_TIMER_NUM];
- uint64_t res5[4*(24-HPET_TIMER_NUM)]; /* reserved, up to 0x3ff */
-
- /* Hidden register state */
- uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
-};
-
-DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
-
-
-/*
- * PM timer
- */
-
-struct hvm_hw_pmtimer {
- uint32_t tmr_val; /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
- uint16_t pm1a_sts; /* PM1a_EVT_BLK.PM1a_STS: status register */
- uint16_t pm1a_en; /* PM1a_EVT_BLK.PM1a_EN: enable register */
-};
-
-DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
-
-/*
- * MTRR MSRs
- */
-
-struct hvm_hw_mtrr {
-#define MTRR_VCNT 8
-#define NUM_FIXED_MSR 11
- uint64_t msr_pat_cr;
- /* mtrr physbase & physmask msr pair*/
- uint64_t msr_mtrr_var[MTRR_VCNT*2];
- uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];
- uint64_t msr_mtrr_cap;
- uint64_t msr_mtrr_def_type;
-};
-
-DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);
-
-/*
- * The save area of XSAVE/XRSTOR.
- */
-
-struct hvm_hw_cpu_xsave {
- uint64_t xfeature_mask; /* Ignored */
- uint64_t xcr0; /* Updated by XSETBV */
- uint64_t xcr0_accum; /* Updated by XSETBV */
- struct {
- struct { char x[512]; } fpu_sse;
-
- struct {
- uint64_t xstate_bv; /* Updated by XRSTOR */
- uint64_t reserved[7];
- } xsave_hdr; /* The 64-byte header */
-
- struct { char x[0]; } ymm; /* YMM */
- } save_area;
-};
-
-#define CPU_XSAVE_CODE 16
-
-/*
- * Viridian hypervisor context.
- */
-
-struct hvm_viridian_domain_context {
- uint64_t hypercall_gpa;
- uint64_t guest_os_id;
- uint64_t time_ref_count;
- uint64_t reference_tsc;
-};
-
-DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context);
-
-struct hvm_viridian_vcpu_context {
- uint64_t apic_assist;
-};
-
-DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);
-
-struct hvm_vmce_vcpu {
- uint64_t caps;
- uint64_t mci_ctl2_bank0;
- uint64_t mci_ctl2_bank1;
-};
-
-DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
-
-struct hvm_tsc_adjust {
- uint64_t tsc_adjust;
-};
-
-DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
-
-
-struct hvm_msr {
- uint32_t count;
- struct hvm_one_msr {
- uint32_t index;
- uint32_t _rsvd;
- uint64_t val;
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- } msr[];
-#elif defined(__GNUC__)
- } msr[0];
-#else
- } msr[1 /* variable size */];
-#endif
-};
-
-#define CPU_MSR_CODE 20
-
-/*
- * Largest type-code in use
- */
-#define HVM_SAVE_CODE_MAX 20
-
-#endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * arch-x86/mca.h
- *
- * Contributed by Advanced Micro Devices, Inc.
- * Author: Christoph Egger <Christoph.Egger@amd.com>
- *
- * Guest OS machine check interface to x86 Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* Full MCA functionality has the following Usecases from the guest side:
- *
- * Must have's:
- * 1. Dom0 and DomU register machine check trap callback handlers
- * (already done via "set_trap_table" hypercall)
- * 2. Dom0 registers machine check event callback handler
- * (doable via EVTCHNOP_bind_virq)
- * 3. Dom0 and DomU fetches machine check data
- * 4. Dom0 wants Xen to notify a DomU
- * 5. Dom0 gets DomU ID from physical address
- * 6. Dom0 wants Xen to kill DomU (already done for "xm destroy")
- *
- * Nice to have's:
- * 7. Dom0 wants Xen to deactivate a physical CPU
- * This is better done as separate task, physical CPU hotplugging,
- * and hypercall(s) should be sysctl's
- * 8. Page migration proposed from Xen NUMA work, where Dom0 can tell Xen to
- * move a DomU (or Dom0 itself) away from a malicious page
- * producing correctable errors.
- * 9. offlining physical page:
- * Xen free's and never re-uses a certain physical page.
- * 10. Testfacility: Allow Dom0 to write values into machine check MSR's
- * and tell Xen to trigger a machine check
- */
-
-#ifndef __XEN_PUBLIC_ARCH_X86_MCA_H__
-#define __XEN_PUBLIC_ARCH_X86_MCA_H__
-
-/* Hypercall */
-#define __HYPERVISOR_mca __HYPERVISOR_arch_0
-
-/*
- * The xen-unstable repo has interface version 0x03000001; out interface
- * is incompatible with that and any future minor revisions, so we
- * choose a different version number range that is numerically less
- * than that used in xen-unstable.
- */
-#define XEN_MCA_INTERFACE_VERSION 0x01ecc003
-
-/* IN: Dom0 calls hypercall to retrieve nonurgent telemetry */
-#define XEN_MC_NONURGENT 0x0001
-/* IN: Dom0/DomU calls hypercall to retrieve urgent telemetry */
-#define XEN_MC_URGENT 0x0002
-/* IN: Dom0 acknowledges previosly-fetched telemetry */
-#define XEN_MC_ACK 0x0004
-
-/* OUT: All is ok */
-#define XEN_MC_OK 0x0
-/* OUT: Domain could not fetch data. */
-#define XEN_MC_FETCHFAILED 0x1
-/* OUT: There was no machine check data to fetch. */
-#define XEN_MC_NODATA 0x2
-/* OUT: Between notification time and this hypercall an other
- * (most likely) correctable error happened. The fetched data,
- * does not match the original machine check data. */
-#define XEN_MC_NOMATCH 0x4
-
-/* OUT: DomU did not register MC NMI handler. Try something else. */
-#define XEN_MC_CANNOTHANDLE 0x8
-/* OUT: Notifying DomU failed. Retry later or try something else. */
-#define XEN_MC_NOTDELIVERED 0x10
-/* Note, XEN_MC_CANNOTHANDLE and XEN_MC_NOTDELIVERED are mutually exclusive. */
-
-
-#ifndef __ASSEMBLY__
-
-#define VIRQ_MCA VIRQ_ARCH_0 /* G. (DOM0) Machine Check Architecture */
-
-/*
- * Machine Check Architecure:
- * structs are read-only and used to report all kinds of
- * correctable and uncorrectable errors detected by the HW.
- * Dom0 and DomU: register a handler to get notified.
- * Dom0 only: Correctable errors are reported via VIRQ_MCA
- * Dom0 and DomU: Uncorrectable errors are reported via nmi handlers
- */
-#define MC_TYPE_GLOBAL 0
-#define MC_TYPE_BANK 1
-#define MC_TYPE_EXTENDED 2
-#define MC_TYPE_RECOVERY 3
-
-struct mcinfo_common {
- uint16_t type; /* structure type */
- uint16_t size; /* size of this struct in bytes */
-};
-
-
-#define MC_FLAG_CORRECTABLE (1 << 0)
-#define MC_FLAG_UNCORRECTABLE (1 << 1)
-#define MC_FLAG_RECOVERABLE (1 << 2)
-#define MC_FLAG_POLLED (1 << 3)
-#define MC_FLAG_RESET (1 << 4)
-#define MC_FLAG_CMCI (1 << 5)
-#define MC_FLAG_MCE (1 << 6)
-/* contains global x86 mc information */
-struct mcinfo_global {
- struct mcinfo_common common;
-
- /* running domain at the time in error (most likely the impacted one) */
- uint16_t mc_domid;
- uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
- uint32_t mc_socketid; /* physical socket of the physical core */
- uint16_t mc_coreid; /* physical impacted core */
- uint16_t mc_core_threadid; /* core thread of physical core */
- uint32_t mc_apicid;
- uint32_t mc_flags;
- uint64_t mc_gstatus; /* global status */
-};
-
-/* contains bank local x86 mc information */
-struct mcinfo_bank {
- struct mcinfo_common common;
-
- uint16_t mc_bank; /* bank nr */
- uint16_t mc_domid; /* Usecase 5: domain referenced by mc_addr on dom0
- * and if mc_addr is valid. Never valid on DomU. */
- uint64_t mc_status; /* bank status */
- uint64_t mc_addr; /* bank address, only valid
- * if addr bit is set in mc_status */
- uint64_t mc_misc;
- uint64_t mc_ctrl2;
- uint64_t mc_tsc;
-};
-
-
-struct mcinfo_msr {
- uint64_t reg; /* MSR */
- uint64_t value; /* MSR value */
-};
-
-/* contains mc information from other
- * or additional mc MSRs */
-struct mcinfo_extended {
- struct mcinfo_common common;
-
- /* You can fill up to five registers.
- * If you need more, then use this structure
- * multiple times. */
-
- uint32_t mc_msrs; /* Number of msr with valid values. */
- /*
- * Currently Intel extended MSR (32/64) include all gp registers
- * and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be
- * useful at present. So expand this array to 16/32 to leave room.
- */
- struct mcinfo_msr mc_msr[sizeof(void *) * 4];
-};
-
-/* Recovery Action flags. Giving recovery result information to DOM0 */
-
-/* Xen takes successful recovery action, the error is recovered */
-#define REC_ACTION_RECOVERED (0x1 << 0)
-/* No action is performed by XEN */
-#define REC_ACTION_NONE (0x1 << 1)
-/* It's possible DOM0 might take action ownership in some case */
-#define REC_ACTION_NEED_RESET (0x1 << 2)
-
-/* Different Recovery Action types, if the action is performed successfully,
- * REC_ACTION_RECOVERED flag will be returned.
- */
-
-/* Page Offline Action */
-#define MC_ACTION_PAGE_OFFLINE (0x1 << 0)
-/* CPU offline Action */
-#define MC_ACTION_CPU_OFFLINE (0x1 << 1)
-/* L3 cache disable Action */
-#define MC_ACTION_CACHE_SHRINK (0x1 << 2)
-
-/* Below interface used between XEN/DOM0 for passing XEN's recovery action
- * information to DOM0.
- * usage Senario: After offlining broken page, XEN might pass its page offline
- * recovery action result to DOM0. DOM0 will save the information in
- * non-volatile memory for further proactive actions, such as offlining the
- * easy broken page earlier when doing next reboot.
-*/
-struct page_offline_action
-{
- /* Params for passing the offlined page number to DOM0 */
- uint64_t mfn;
- uint64_t status;
-};
-
-struct cpu_offline_action
-{
- /* Params for passing the identity of the offlined CPU to DOM0 */
- uint32_t mc_socketid;
- uint16_t mc_coreid;
- uint16_t mc_core_threadid;
-};
-
-#define MAX_UNION_SIZE 16
-struct mcinfo_recovery
-{
- struct mcinfo_common common;
- uint16_t mc_bank; /* bank nr */
- uint8_t action_flags;
- uint8_t action_types;
- union {
- struct page_offline_action page_retire;
- struct cpu_offline_action cpu_offline;
- uint8_t pad[MAX_UNION_SIZE];
- } action_info;
-};
-
-
-#define MCINFO_HYPERCALLSIZE 1024
-#define MCINFO_MAXSIZE 768
-
-#define MCINFO_FLAGS_UNCOMPLETE 0x1
-struct mc_info {
- /* Number of mcinfo_* entries in mi_data */
- uint32_t mi_nentries;
- uint32_t flags;
- uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
-};
-typedef struct mc_info mc_info_t;
-DEFINE_XEN_GUEST_HANDLE(mc_info_t);
-
-#define __MC_MSR_ARRAYSIZE 8
-#define __MC_NMSRS 1
-#define MC_NCAPS 7 /* 7 CPU feature flag words */
-#define MC_CAPS_STD_EDX 0 /* cpuid level 0x00000001 (%edx) */
-#define MC_CAPS_AMD_EDX 1 /* cpuid level 0x80000001 (%edx) */
-#define MC_CAPS_TM 2 /* cpuid level 0x80860001 (TransMeta) */
-#define MC_CAPS_LINUX 3 /* Linux-defined */
-#define MC_CAPS_STD_ECX 4 /* cpuid level 0x00000001 (%ecx) */
-#define MC_CAPS_VIA 5 /* cpuid level 0xc0000001 */
-#define MC_CAPS_AMD_ECX 6 /* cpuid level 0x80000001 (%ecx) */
-
-struct mcinfo_logical_cpu {
- uint32_t mc_cpunr;
- uint32_t mc_chipid;
- uint16_t mc_coreid;
- uint16_t mc_threadid;
- uint32_t mc_apicid;
- uint32_t mc_clusterid;
- uint32_t mc_ncores;
- uint32_t mc_ncores_active;
- uint32_t mc_nthreads;
- int32_t mc_cpuid_level;
- uint32_t mc_family;
- uint32_t mc_vendor;
- uint32_t mc_model;
- uint32_t mc_step;
- char mc_vendorid[16];
- char mc_brandid[64];
- uint32_t mc_cpu_caps[MC_NCAPS];
- uint32_t mc_cache_size;
- uint32_t mc_cache_alignment;
- int32_t mc_nmsrvals;
- struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE];
-};
-typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t);
-
-
-/*
- * OS's should use these instead of writing their own lookup function
- * each with its own bugs and drawbacks.
- * We use macros instead of static inline functions to allow guests
- * to include this header in assembly files (*.S).
- */
-/* Prototype:
- * uint32_t x86_mcinfo_nentries(struct mc_info *mi);
- */
-#define x86_mcinfo_nentries(_mi) \
- (_mi)->mi_nentries
-/* Prototype:
- * struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi);
- */
-#define x86_mcinfo_first(_mi) \
- ((struct mcinfo_common *)(_mi)->mi_data)
-/* Prototype:
- * struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic);
- */
-#define x86_mcinfo_next(_mic) \
- ((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size))
-
-/* Prototype:
- * void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type);
- */
-#define x86_mcinfo_lookup(_ret, _mi, _type) \
- do { \
- uint32_t found, i; \
- struct mcinfo_common *_mic; \
- \
- found = 0; \
- (_ret) = NULL; \
- if (_mi == NULL) break; \
- _mic = x86_mcinfo_first(_mi); \
- for (i = 0; i < x86_mcinfo_nentries(_mi); i++) { \
- if (_mic->type == (_type)) { \
- found = 1; \
- break; \
- } \
- _mic = x86_mcinfo_next(_mic); \
- } \
- (_ret) = found ? _mic : NULL; \
- } while (0)
-
-
-/* Usecase 1
- * Register machine check trap callback handler
- * (already done via "set_trap_table" hypercall)
- */
-
-/* Usecase 2
- * Dom0 registers machine check event callback handler
- * done by EVTCHNOP_bind_virq
- */
-
-/* Usecase 3
- * Fetch machine check data from hypervisor.
- * Note, this hypercall is special, because both Dom0 and DomU must use this.
- */
-#define XEN_MC_fetch 1
-struct xen_mc_fetch {
- /* IN/OUT variables. */
- uint32_t flags; /* IN: XEN_MC_NONURGENT, XEN_MC_URGENT,
- XEN_MC_ACK if ack'ing an earlier fetch */
- /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED,
- XEN_MC_NODATA, XEN_MC_NOMATCH */
- uint32_t _pad0;
- uint64_t fetch_id; /* OUT: id for ack, IN: id we are ack'ing */
-
- /* OUT variables. */
- XEN_GUEST_HANDLE(mc_info_t) data;
-};
-typedef struct xen_mc_fetch xen_mc_fetch_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mc_fetch_t);
-
-
-/* Usecase 4
- * This tells the hypervisor to notify a DomU about the machine check error
- */
-#define XEN_MC_notifydomain 2
-struct xen_mc_notifydomain {
- /* IN variables. */
- uint16_t mc_domid; /* The unprivileged domain to notify. */
- uint16_t mc_vcpuid; /* The vcpu in mc_domid to notify.
- * Usually echo'd value from the fetch hypercall. */
-
- /* IN/OUT variables. */
- uint32_t flags;
-
-/* IN: XEN_MC_CORRECTABLE, XEN_MC_TRAP */
-/* OUT: XEN_MC_OK, XEN_MC_CANNOTHANDLE, XEN_MC_NOTDELIVERED, XEN_MC_NOMATCH */
-};
-typedef struct xen_mc_notifydomain xen_mc_notifydomain_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t);
-
-#define XEN_MC_physcpuinfo 3
-struct xen_mc_physcpuinfo {
- /* IN/OUT */
- uint32_t ncpus;
- uint32_t _pad0;
- /* OUT */
- XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info;
-};
-
-#define XEN_MC_msrinject 4
-#define MC_MSRINJ_MAXMSRS 8
-struct xen_mc_msrinject {
- /* IN */
- uint32_t mcinj_cpunr; /* target processor id */
- uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */
- uint32_t mcinj_count; /* 0 .. count-1 in array are valid */
- uint32_t _pad0;
- struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS];
-};
-
-/* Flags for mcinj_flags above; bits 16-31 are reserved */
-#define MC_MSRINJ_F_INTERPOSE 0x1
-
-#define XEN_MC_mceinject 5
-struct xen_mc_mceinject {
- unsigned int mceinj_cpunr; /* target processor id */
-};
-
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-#define XEN_MC_inject_v2 6
-#define XEN_MC_INJECT_TYPE_MASK 0x7
-#define XEN_MC_INJECT_TYPE_MCE 0x0
-#define XEN_MC_INJECT_TYPE_CMCI 0x1
-
-#define XEN_MC_INJECT_CPU_BROADCAST 0x8
-
-struct xen_mc_inject_v2 {
- uint32_t flags;
- struct xenctl_bitmap cpumap;
-};
-#endif
-
-struct xen_mc {
- uint32_t cmd;
- uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
- union {
- struct xen_mc_fetch mc_fetch;
- struct xen_mc_notifydomain mc_notifydomain;
- struct xen_mc_physcpuinfo mc_physcpuinfo;
- struct xen_mc_msrinject mc_msrinject;
- struct xen_mc_mceinject mc_mceinject;
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
- struct xen_mc_inject_v2 mc_inject_v2;
-#endif
- } u;
-};
-typedef struct xen_mc xen_mc_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mc_t);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */
+++ /dev/null
-/******************************************************************************
- * xen-x86_32.h
- *
- * Guest OS interface to x86 32-bit Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004-2007, K A Fraser
- */
-
-#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
-#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
-
-/*
- * Hypercall interface:
- * Input: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6)
- * Output: %eax
- * Access is via hypercall page (set up by guest loader or via a Xen MSR):
- * call hypercall_page + hypercall-number * 32
- * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx)
- */
-
-/*
- * These flat segments are in the Xen-private section of every GDT. Since these
- * are also present in the initial GDT, many OSes will be able to avoid
- * installing their own GDT.
- */
-#define FLAT_RING1_CS 0xe019 /* GDT index 259 */
-#define FLAT_RING1_DS 0xe021 /* GDT index 260 */
-#define FLAT_RING1_SS 0xe021 /* GDT index 260 */
-#define FLAT_RING3_CS 0xe02b /* GDT index 261 */
-#define FLAT_RING3_DS 0xe033 /* GDT index 262 */
-#define FLAT_RING3_SS 0xe033 /* GDT index 262 */
-
-#define FLAT_KERNEL_CS FLAT_RING1_CS
-#define FLAT_KERNEL_DS FLAT_RING1_DS
-#define FLAT_KERNEL_SS FLAT_RING1_SS
-#define FLAT_USER_CS FLAT_RING3_CS
-#define FLAT_USER_DS FLAT_RING3_DS
-#define FLAT_USER_SS FLAT_RING3_SS
-
-#define __HYPERVISOR_VIRT_START_PAE 0xF5800000
-#define __MACH2PHYS_VIRT_START_PAE 0xF5800000
-#define __MACH2PHYS_VIRT_END_PAE 0xF6800000
-#define HYPERVISOR_VIRT_START_PAE \
- mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE)
-#define MACH2PHYS_VIRT_START_PAE \
- mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE)
-#define MACH2PHYS_VIRT_END_PAE \
- mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE)
-
-/* Non-PAE bounds are obsolete. */
-#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000
-#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000
-#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000
-#define HYPERVISOR_VIRT_START_NONPAE \
- mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE)
-#define MACH2PHYS_VIRT_START_NONPAE \
- mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE)
-#define MACH2PHYS_VIRT_END_NONPAE \
- mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE)
-
-#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE
-#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE
-#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE
-
-#ifndef HYPERVISOR_VIRT_START
-#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-#endif
-
-#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
-#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
-#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2)
-#ifndef machine_to_phys_mapping
-#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
-#endif
-
-/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-#undef ___DEFINE_XEN_GUEST_HANDLE
-#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
- typedef struct { type *p; } \
- __guest_handle_ ## name; \
- typedef struct { union { type *p; uint64_aligned_t q; }; } \
- __guest_handle_64_ ## name
-#undef set_xen_guest_handle_raw
-#define set_xen_guest_handle_raw(hnd, val) \
- do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \
- (hnd).p = val; \
- } while ( 0 )
-#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-#define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
-#define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name)
-#endif
-
-#ifndef __ASSEMBLY__
-
-struct cpu_user_regs {
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t eax;
- uint16_t error_code; /* private */
- uint16_t entry_vector; /* private */
- uint32_t eip;
- uint16_t cs;
- uint8_t saved_upcall_mask;
- uint8_t _pad0;
- uint32_t eflags; /* eflags.IF == !saved_upcall_mask */
- uint32_t esp;
- uint16_t ss, _pad1;
- uint16_t es, _pad2;
- uint16_t ds, _pad3;
- uint16_t fs, _pad4;
- uint16_t gs, _pad5;
-};
-typedef struct cpu_user_regs cpu_user_regs_t;
-DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
-
-/*
- * Page-directory addresses above 4GB do not fit into architectural %cr3.
- * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
- * must use the following accessor macros to pack/unpack valid MFNs.
- */
-#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
-#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
-
-struct arch_vcpu_info {
- unsigned long cr2;
- unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
-};
-typedef struct arch_vcpu_info arch_vcpu_info_t;
-
-struct xen_callback {
- unsigned long cs;
- unsigned long eip;
-};
-typedef struct xen_callback xen_callback_t;
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * xen-x86_64.h
- *
- * Guest OS interface to x86 64-bit Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004-2006, K A Fraser
- */
-
-#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
-#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
-
-/*
- * Hypercall interface:
- * Input: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
- * Output: %rax
- * Access is via hypercall page (set up by guest loader or via a Xen MSR):
- * call hypercall_page + hypercall-number * 32
- * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi)
- */
-
-/*
- * 64-bit segment selectors
- * These flat segments are in the Xen-private section of every GDT. Since these
- * are also present in the initial GDT, many OSes will be able to avoid
- * installing their own GDT.
- */
-
-#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */
-#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */
-#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */
-#define FLAT_RING3_DS64 0x0000 /* NULL selector */
-#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */
-#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */
-
-#define FLAT_KERNEL_DS64 FLAT_RING3_DS64
-#define FLAT_KERNEL_DS32 FLAT_RING3_DS32
-#define FLAT_KERNEL_DS FLAT_KERNEL_DS64
-#define FLAT_KERNEL_CS64 FLAT_RING3_CS64
-#define FLAT_KERNEL_CS32 FLAT_RING3_CS32
-#define FLAT_KERNEL_CS FLAT_KERNEL_CS64
-#define FLAT_KERNEL_SS64 FLAT_RING3_SS64
-#define FLAT_KERNEL_SS32 FLAT_RING3_SS32
-#define FLAT_KERNEL_SS FLAT_KERNEL_SS64
-
-#define FLAT_USER_DS64 FLAT_RING3_DS64
-#define FLAT_USER_DS32 FLAT_RING3_DS32
-#define FLAT_USER_DS FLAT_USER_DS64
-#define FLAT_USER_CS64 FLAT_RING3_CS64
-#define FLAT_USER_CS32 FLAT_RING3_CS32
-#define FLAT_USER_CS FLAT_USER_CS64
-#define FLAT_USER_SS64 FLAT_RING3_SS64
-#define FLAT_USER_SS32 FLAT_RING3_SS32
-#define FLAT_USER_SS FLAT_USER_SS64
-
-#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
-#define __HYPERVISOR_VIRT_END 0xFFFF880000000000
-#define __MACH2PHYS_VIRT_START 0xFFFF800000000000
-#define __MACH2PHYS_VIRT_END 0xFFFF804000000000
-
-#ifndef HYPERVISOR_VIRT_START
-#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
-#endif
-
-#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
-#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
-#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
-#ifndef machine_to_phys_mapping
-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
-#endif
-
-/*
- * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
- * @which == SEGBASE_* ; @base == 64-bit base address
- * Returns 0 on success.
- */
-#define SEGBASE_FS 0
-#define SEGBASE_GS_USER 1
-#define SEGBASE_GS_KERNEL 2
-#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
-
-/*
- * int HYPERVISOR_iret(void)
- * All arguments are on the kernel stack, in the following format.
- * Never returns if successful. Current kernel context is lost.
- * The saved CS is mapped as follows:
- * RING0 -> RING3 kernel mode.
- * RING1 -> RING3 kernel mode.
- * RING2 -> RING3 kernel mode.
- * RING3 -> RING3 user mode.
- * However RING0 indicates that the guest kernel should return to iteself
- * directly with
- * orb $3,1*8(%rsp)
- * iretq
- * If flags contains VGCF_in_syscall:
- * Restore RAX, RIP, RFLAGS, RSP.
- * Discard R11, RCX, CS, SS.
- * Otherwise:
- * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
- * All other registers are saved on hypercall entry and restored to user.
- */
-/* Guest exited in SYSCALL context? Return to guest with SYSRET? */
-#define _VGCF_in_syscall 8
-#define VGCF_in_syscall (1<<_VGCF_in_syscall)
-#define VGCF_IN_SYSCALL VGCF_in_syscall
-
-#ifndef __ASSEMBLY__
-
-struct iret_context {
- /* Top of stack (%rsp at point of hypercall). */
- uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
- /* Bottom of iret stack frame. */
-};
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
-#define __DECL_REG(name) union { \
- uint64_t r ## name, e ## name; \
- uint32_t _e ## name; \
-}
-#else
-/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
-#define __DECL_REG(name) uint64_t r ## name
-#endif
-
-struct cpu_user_regs {
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- __DECL_REG(bp);
- __DECL_REG(bx);
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
- __DECL_REG(ax);
- __DECL_REG(cx);
- __DECL_REG(dx);
- __DECL_REG(si);
- __DECL_REG(di);
- uint32_t error_code; /* private */
- uint32_t entry_vector; /* private */
- __DECL_REG(ip);
- uint16_t cs, _pad0[1];
- uint8_t saved_upcall_mask;
- uint8_t _pad1[3];
- __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */
- __DECL_REG(sp);
- uint16_t ss, _pad2[3];
- uint16_t es, _pad3[3];
- uint16_t ds, _pad4[3];
- uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */
- uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
-};
-typedef struct cpu_user_regs cpu_user_regs_t;
-DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
-
-#undef __DECL_REG
-
-#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
-#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
-
-struct arch_vcpu_info {
- unsigned long cr2;
- unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
-};
-typedef struct arch_vcpu_info arch_vcpu_info_t;
-
-typedef unsigned long xen_callback_t;
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * arch-x86/xen.h
- *
- * Guest OS interface to x86 Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004-2006, K A Fraser
- */
-
-#include "../xen.h"
-
-#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__
-#define __XEN_PUBLIC_ARCH_X86_XEN_H__
-
-/* Structural guest handles introduced in 0x00030201. */
-#if __XEN_INTERFACE_VERSION__ >= 0x00030201
-#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
- typedef struct { type *p; } __guest_handle_ ## name
-#else
-#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
- typedef type * __guest_handle_ ## name
-#endif
-
-/*
- * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
- * in a struct in memory.
- * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
- * hypercall argument.
- * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but
- * they might not be on other architectures.
- */
-#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
- ___DEFINE_XEN_GUEST_HANDLE(name, type); \
- ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
-#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
-#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name
-#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
-#define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name)
-#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0)
-#ifdef __XEN_TOOLS__
-#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
-#endif
-#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
-
-#if defined(__i386__)
-#include "xen-x86_32.h"
-#elif defined(__x86_64__)
-#include "xen-x86_64.h"
-#endif
-
-#ifndef __ASSEMBLY__
-typedef unsigned long xen_pfn_t;
-#define PRI_xen_pfn "lx"
-#endif
-
-#define XEN_HAVE_PV_GUEST_ENTRY 1
-
-#define XEN_HAVE_PV_UPCALL_MASK 1
-
-/*
- * `incontents 200 segdesc Segment Descriptor Tables
- */
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_set_gdt(const xen_pfn_t frames[], unsigned int entries);
- * `
- */
-/*
- * A number of GDT entries are reserved by Xen. These are not situated at the
- * start of the GDT because some stupid OSes export hard-coded selector values
- * in their ABI. These hard-coded values are always near the start of the GDT,
- * so Xen places itself out of the way, at the far end of the GDT.
- *
- * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op
- */
-#define FIRST_RESERVED_GDT_PAGE 14
-#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096)
-#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
-
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_update_descriptor(u64 pa, u64 desc);
- * `
- * ` @pa The machine physical address of the descriptor to
- * ` update. Must be either a descriptor page or writable.
- * ` @desc The descriptor value to update, in the same format as a
- * ` native descriptor table entry.
- */
-
-/* Maximum number of virtual CPUs in legacy multi-processor guests. */
-#define XEN_LEGACY_MAX_VCPUS 32
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned long xen_ulong_t;
-#define PRI_xen_ulong "lx"
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp);
- * `
- * Sets the stack segment and pointer for the current vcpu.
- */
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_set_trap_table(const struct trap_info traps[]);
- * `
- */
-/*
- * Send an array of these to HYPERVISOR_set_trap_table().
- * Terminate the array with a sentinel entry, with traps[].address==0.
- * The privilege level specifies which modes may enter a trap via a software
- * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
- * privilege levels as follows:
- * Level == 0: Noone may enter
- * Level == 1: Kernel may enter
- * Level == 2: Kernel may enter
- * Level == 3: Everyone may enter
- */
-#define TI_GET_DPL(_ti) ((_ti)->flags & 3)
-#define TI_GET_IF(_ti) ((_ti)->flags & 4)
-#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
-#define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2))
-struct trap_info {
- uint8_t vector; /* exception vector */
- uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */
- uint16_t cs; /* code selector */
- unsigned long address; /* code offset */
-};
-typedef struct trap_info trap_info_t;
-DEFINE_XEN_GUEST_HANDLE(trap_info_t);
-
-typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
-
-/*
- * The following is all CPU context. Note that the fpu_ctxt block is filled
- * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
- *
- * Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise
- * for HVM and PVH guests, not all information in this structure is updated:
- *
- * - For HVM guests, the structures read include: fpu_ctxt (if
- * VGCT_I387_VALID is set), flags, user_regs, debugreg[*]
- *
- * - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to
- * set cr3. All other fields not used should be set to 0.
- */
-struct vcpu_guest_context {
- /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
- struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */
-#define VGCF_I387_VALID (1<<0)
-#define VGCF_IN_KERNEL (1<<2)
-#define _VGCF_i387_valid 0
-#define VGCF_i387_valid (1<<_VGCF_i387_valid)
-#define _VGCF_in_kernel 2
-#define VGCF_in_kernel (1<<_VGCF_in_kernel)
-#define _VGCF_failsafe_disables_events 3
-#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events)
-#define _VGCF_syscall_disables_events 4
-#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events)
-#define _VGCF_online 5
-#define VGCF_online (1<<_VGCF_online)
- unsigned long flags; /* VGCF_* flags */
- struct cpu_user_regs user_regs; /* User-level CPU registers */
- struct trap_info trap_ctxt[256]; /* Virtual IDT */
- unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */
- unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
- unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */
- /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
- unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */
- unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */
-#ifdef __i386__
- unsigned long event_callback_cs; /* CS:EIP of event callback */
- unsigned long event_callback_eip;
- unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */
- unsigned long failsafe_callback_eip;
-#else
- unsigned long event_callback_eip;
- unsigned long failsafe_callback_eip;
-#ifdef __XEN__
- union {
- unsigned long syscall_callback_eip;
- struct {
- unsigned int event_callback_cs; /* compat CS of event cb */
- unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */
- };
- };
-#else
- unsigned long syscall_callback_eip;
-#endif
-#endif
- unsigned long vm_assist; /* VMASST_TYPE_* bitmap */
-#ifdef __x86_64__
- /* Segment base addresses. */
- uint64_t fs_base;
- uint64_t gs_base_kernel;
- uint64_t gs_base_user;
-#endif
-};
-typedef struct vcpu_guest_context vcpu_guest_context_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-
-struct arch_shared_info {
- /*
- * Number of valid entries in the p2m table(s) anchored at
- * pfn_to_mfn_frame_list_list and/or p2m_vaddr.
- */
- unsigned long max_pfn;
- /*
- * Frame containing list of mfns containing list of mfns containing p2m.
- * A value of 0 indicates it has not yet been set up, ~0 indicates it has
- * been set to invalid e.g. due to the p2m being too large for the 3-level
- * p2m tree. In this case the linear mapper p2m list anchored at p2m_vaddr
- * is to be used.
- */
- xen_pfn_t pfn_to_mfn_frame_list_list;
- unsigned long nmi_reason;
- /*
- * Following three fields are valid if p2m_cr3 contains a value different
- * from 0.
- * p2m_cr3 is the root of the address space where p2m_vaddr is valid.
- * p2m_cr3 is in the same format as a cr3 value in the vcpu register state
- * and holds the folded machine frame number (via xen_pfn_to_cr3) of a
- * L3 or L4 page table.
- * p2m_vaddr holds the virtual address of the linear p2m list. All entries
- * in the range [0...max_pfn[ are accessible via this pointer.
- * p2m_generation will be incremented by the guest before and after each
- * change of the mappings of the p2m list. p2m_generation starts at 0 and
- * a value with the least significant bit set indicates that a mapping
- * update is in progress. This allows guest external software (e.g. in Dom0)
- * to verify that read mappings are consistent and whether they have changed
- * since the last check.
- * Modifying a p2m element in the linear p2m list is allowed via an atomic
- * write only.
- */
- unsigned long p2m_cr3; /* cr3 value of the p2m address space */
- unsigned long p2m_vaddr; /* virtual address of the p2m list */
- unsigned long p2m_generation; /* generation count of p2m mapping */
-};
-typedef struct arch_shared_info arch_shared_info_t;
-
-#endif /* !__ASSEMBLY__ */
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_fpu_taskswitch(int set);
- * `
- * Sets (if set!=0) or clears (if set==0) CR0.TS.
- */
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_set_debugreg(int regno, unsigned long value);
- *
- * ` unsigned long
- * ` HYPERVISOR_get_debugreg(int regno);
- * For 0<=reg<=7, returns the debug register value.
- * For other values of reg, returns ((unsigned long)-EINVAL).
- * (Unfortunately, this interface is defective.)
- */
-
-/*
- * Prefix forces emulation of some non-trapping instructions.
- * Currently only CPUID.
- */
-#ifdef __ASSEMBLY__
-#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
-#define XEN_CPUID XEN_EMULATE_PREFIX cpuid
-#else
-#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
-#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
-#endif
-
-#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * arch-x86_32.h
- *
- * Guest OS interface to x86 32-bit Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004-2006, K A Fraser
- */
-
-#include "arch-x86/xen.h"
+++ /dev/null
-/******************************************************************************
- * arch-x86_64.h
- *
- * Guest OS interface to x86 64-bit Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004-2006, K A Fraser
- */
-
-#include "arch-x86/xen.h"
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_set_callbacks(unsigned long event_selector,
- * ` unsigned long event_address,
- * ` unsigned long failsafe_selector,
- * ` unsigned long failsafe_address);
- * `
- * Register for callbacks on events. When an event (from an event
- * channel) occurs, event_address is used as the value of eip.
- *
- * A similar callback occurs if the segment selectors are invalid.
- * failsafe_address is used as the value of eip.
- *
- * On x86_64, event_selector and failsafe_selector are ignored (???).
- */
+++ /dev/null
-/******************************************************************************
- * callback.h
- *
- * Register guest OS callbacks with Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2006, Ian Campbell
- */
-
-#ifndef __XEN_PUBLIC_CALLBACK_H__
-#define __XEN_PUBLIC_CALLBACK_H__
-
-#include "xen.h"
-
-/*
- * Prototype for this hypercall is:
- * long callback_op(int cmd, void *extra_args)
- * @cmd == CALLBACKOP_??? (callback operation).
- * @extra_args == Operation-specific extra arguments (NULL if none).
- */
-
-/* x86: Callback for event delivery. */
-#define CALLBACKTYPE_event 0
-
-/* x86: Failsafe callback when guest state cannot be restored by Xen. */
-#define CALLBACKTYPE_failsafe 1
-
-/* x86/64 hypervisor: Syscall by 64-bit guest app ('64-on-64-on-64'). */
-#define CALLBACKTYPE_syscall 2
-
-/*
- * x86/32 hypervisor: Only available on x86/32 when supervisor_mode_kernel
- * feature is enabled. Do not use this callback type in new code.
- */
-#define CALLBACKTYPE_sysenter_deprecated 3
-
-/* x86: Callback for NMI delivery. */
-#define CALLBACKTYPE_nmi 4
-
-/*
- * x86: sysenter is only available as follows:
- * - 32-bit hypervisor: with the supervisor_mode_kernel feature enabled
- * - 64-bit hypervisor: 32-bit guest applications on Intel CPUs
- * ('32-on-32-on-64', '32-on-64-on-64')
- * [nb. also 64-bit guest applications on Intel CPUs
- * ('64-on-64-on-64'), but syscall is preferred]
- */
-#define CALLBACKTYPE_sysenter 5
-
-/*
- * x86/64 hypervisor: Syscall by 32-bit guest app on AMD CPUs
- * ('32-on-32-on-64', '32-on-64-on-64')
- */
-#define CALLBACKTYPE_syscall32 7
-
-/*
- * Disable event deliver during callback? This flag is ignored for event and
- * NMI callbacks: event delivery is unconditionally disabled.
- */
-#define _CALLBACKF_mask_events 0
-#define CALLBACKF_mask_events (1U << _CALLBACKF_mask_events)
-
-/*
- * Register a callback.
- */
-#define CALLBACKOP_register 0
-struct callback_register {
- uint16_t type;
- uint16_t flags;
- xen_callback_t address;
-};
-typedef struct callback_register callback_register_t;
-DEFINE_XEN_GUEST_HANDLE(callback_register_t);
-
-/*
- * Unregister a callback.
- *
- * Not all callbacks can be unregistered. -EINVAL will be returned if
- * you attempt to unregister such a callback.
- */
-#define CALLBACKOP_unregister 1
-struct callback_unregister {
- uint16_t type;
- uint16_t _unused;
-};
-typedef struct callback_unregister callback_unregister_t;
-DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);
-
-#if __XEN_INTERFACE_VERSION__ < 0x00030207
-#undef CALLBACKTYPE_sysenter
-#define CALLBACKTYPE_sysenter CALLBACKTYPE_sysenter_deprecated
-#endif
-
-#endif /* __XEN_PUBLIC_CALLBACK_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * dom0_ops.h
- *
- * Process command requests from domain-0 guest OS.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2002-2003, B Dragovic
- * Copyright (c) 2002-2006, K Fraser
- */
-
-#ifndef __XEN_PUBLIC_DOM0_OPS_H__
-#define __XEN_PUBLIC_DOM0_OPS_H__
-
-#include "xen.h"
-#include "platform.h"
-
-#if __XEN_INTERFACE_VERSION__ >= 0x00030204
-#error "dom0_ops.h is a compatibility interface only"
-#endif
-
-#define DOM0_INTERFACE_VERSION XENPF_INTERFACE_VERSION
-
-#define DOM0_SETTIME XENPF_settime
-#define dom0_settime xenpf_settime
-#define dom0_settime_t xenpf_settime_t
-
-#define DOM0_ADD_MEMTYPE XENPF_add_memtype
-#define dom0_add_memtype xenpf_add_memtype
-#define dom0_add_memtype_t xenpf_add_memtype_t
-
-#define DOM0_DEL_MEMTYPE XENPF_del_memtype
-#define dom0_del_memtype xenpf_del_memtype
-#define dom0_del_memtype_t xenpf_del_memtype_t
-
-#define DOM0_READ_MEMTYPE XENPF_read_memtype
-#define dom0_read_memtype xenpf_read_memtype
-#define dom0_read_memtype_t xenpf_read_memtype_t
-
-#define DOM0_MICROCODE XENPF_microcode_update
-#define dom0_microcode xenpf_microcode_update
-#define dom0_microcode_t xenpf_microcode_update_t
-
-#define DOM0_PLATFORM_QUIRK XENPF_platform_quirk
-#define dom0_platform_quirk xenpf_platform_quirk
-#define dom0_platform_quirk_t xenpf_platform_quirk_t
-
-typedef uint64_t cpumap_t;
-
-/* Unsupported legacy operation -- defined for API compatibility. */
-#define DOM0_MSR 15
-struct dom0_msr {
- /* IN variables. */
- uint32_t write;
- cpumap_t cpu_mask;
- uint32_t msr;
- uint32_t in1;
- uint32_t in2;
- /* OUT variables. */
- uint32_t out1;
- uint32_t out2;
-};
-typedef struct dom0_msr dom0_msr_t;
-DEFINE_XEN_GUEST_HANDLE(dom0_msr_t);
-
-/* Unsupported legacy operation -- defined for API compatibility. */
-#define DOM0_PHYSICAL_MEMORY_MAP 40
-struct dom0_memory_map_entry {
- uint64_t start, end;
- uint32_t flags; /* reserved */
- uint8_t is_ram;
-};
-typedef struct dom0_memory_map_entry dom0_memory_map_entry_t;
-DEFINE_XEN_GUEST_HANDLE(dom0_memory_map_entry_t);
-
-struct dom0_op {
- uint32_t cmd;
- uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
- union {
- struct dom0_msr msr;
- struct dom0_settime settime;
- struct dom0_add_memtype add_memtype;
- struct dom0_del_memtype del_memtype;
- struct dom0_read_memtype read_memtype;
- struct dom0_microcode microcode;
- struct dom0_platform_quirk platform_quirk;
- struct dom0_memory_map_entry physical_memory_map;
- uint8_t pad[128];
- } u;
-};
-typedef struct dom0_op dom0_op_t;
-DEFINE_XEN_GUEST_HANDLE(dom0_op_t);
-
-#endif /* __XEN_PUBLIC_DOM0_OPS_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * domctl.h
- *
- * Domain management operations. For use by node control stack.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2002-2003, B Dragovic
- * Copyright (c) 2002-2006, K Fraser
- */
-
-#ifndef __XEN_PUBLIC_DOMCTL_H__
-#define __XEN_PUBLIC_DOMCTL_H__
-
-#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
-#error "domctl operations are intended for use by node control tools only"
-#endif
-
-#include "xen.h"
-#include "grant_table.h"
-#include "hvm/save.h"
-#include "memory.h"
-
-#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000a
-
-/*
- * NB. xen_domctl.domain is an IN/OUT parameter for this operation.
- * If it is specified as zero, an id is auto-allocated and returned.
- */
-/* XEN_DOMCTL_createdomain */
-struct xen_domctl_createdomain {
- /* IN parameters */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- /* Is this an HVM guest (as opposed to a PVH or PV guest)? */
-#define _XEN_DOMCTL_CDF_hvm_guest 0
-#define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest)
- /* Use hardware-assisted paging if available? */
-#define _XEN_DOMCTL_CDF_hap 1
-#define XEN_DOMCTL_CDF_hap (1U<<_XEN_DOMCTL_CDF_hap)
- /* Should domain memory integrity be verifed by tboot during Sx? */
-#define _XEN_DOMCTL_CDF_s3_integrity 2
-#define XEN_DOMCTL_CDF_s3_integrity (1U<<_XEN_DOMCTL_CDF_s3_integrity)
- /* Disable out-of-sync shadow page tables? */
-#define _XEN_DOMCTL_CDF_oos_off 3
-#define XEN_DOMCTL_CDF_oos_off (1U<<_XEN_DOMCTL_CDF_oos_off)
- /* Is this a PVH guest (as opposed to an HVM or PV guest)? */
-#define _XEN_DOMCTL_CDF_pvh_guest 4
-#define XEN_DOMCTL_CDF_pvh_guest (1U<<_XEN_DOMCTL_CDF_pvh_guest)
- uint32_t flags;
-};
-typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
-
-#if defined(__arm__) || defined(__aarch64__)
-#define XEN_DOMCTL_CONFIG_GIC_DEFAULT 0
-#define XEN_DOMCTL_CONFIG_GIC_V2 1
-#define XEN_DOMCTL_CONFIG_GIC_V3 2
-/* XEN_DOMCTL_configure_domain */
-struct xen_domctl_arm_configuredomain {
- /* IN/OUT parameters */
- uint8_t gic_version;
-};
-typedef struct xen_domctl_arm_configuredomain xen_domctl_arm_configuredomain_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_arm_configuredomain_t);
-#endif
-
-/* XEN_DOMCTL_getdomaininfo */
-struct xen_domctl_getdomaininfo {
- /* OUT variables. */
- domid_t domain; /* Also echoed in domctl.domain */
- /* Domain is scheduled to die. */
-#define _XEN_DOMINF_dying 0
-#define XEN_DOMINF_dying (1U<<_XEN_DOMINF_dying)
- /* Domain is an HVM guest (as opposed to a PV guest). */
-#define _XEN_DOMINF_hvm_guest 1
-#define XEN_DOMINF_hvm_guest (1U<<_XEN_DOMINF_hvm_guest)
- /* The guest OS has shut down. */
-#define _XEN_DOMINF_shutdown 2
-#define XEN_DOMINF_shutdown (1U<<_XEN_DOMINF_shutdown)
- /* Currently paused by control software. */
-#define _XEN_DOMINF_paused 3
-#define XEN_DOMINF_paused (1U<<_XEN_DOMINF_paused)
- /* Currently blocked pending an event. */
-#define _XEN_DOMINF_blocked 4
-#define XEN_DOMINF_blocked (1U<<_XEN_DOMINF_blocked)
- /* Domain is currently running. */
-#define _XEN_DOMINF_running 5
-#define XEN_DOMINF_running (1U<<_XEN_DOMINF_running)
- /* Being debugged. */
-#define _XEN_DOMINF_debugged 6
-#define XEN_DOMINF_debugged (1U<<_XEN_DOMINF_debugged)
-/* domain is PVH */
-#define _XEN_DOMINF_pvh_guest 7
-#define XEN_DOMINF_pvh_guest (1U<<_XEN_DOMINF_pvh_guest)
- /* XEN_DOMINF_shutdown guest-supplied code. */
-#define XEN_DOMINF_shutdownmask 255
-#define XEN_DOMINF_shutdownshift 16
- uint32_t flags; /* XEN_DOMINF_* */
- uint64_aligned_t tot_pages;
- uint64_aligned_t max_pages;
- uint64_aligned_t outstanding_pages;
- uint64_aligned_t shr_pages;
- uint64_aligned_t paged_pages;
- uint64_aligned_t shared_info_frame; /* GMFN of shared_info struct */
- uint64_aligned_t cpu_time;
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
-#define XEN_INVALID_MAX_VCPU_ID (~0U) /* Domain has no vcpus? */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- uint32_t cpupool;
-};
-typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
-
-
-/* XEN_DOMCTL_getmemlist */
-struct xen_domctl_getmemlist {
- /* IN variables. */
- /* Max entries to write to output buffer. */
- uint64_aligned_t max_pfns;
- /* Start index in guest's page list. */
- uint64_aligned_t start_pfn;
- XEN_GUEST_HANDLE_64(uint64) buffer;
- /* OUT variables. */
- uint64_aligned_t num_pfns;
-};
-typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t);
-
-
-/* XEN_DOMCTL_getpageframeinfo */
-
-#define XEN_DOMCTL_PFINFO_LTAB_SHIFT 28
-#define XEN_DOMCTL_PFINFO_NOTAB (0x0U<<28)
-#define XEN_DOMCTL_PFINFO_L1TAB (0x1U<<28)
-#define XEN_DOMCTL_PFINFO_L2TAB (0x2U<<28)
-#define XEN_DOMCTL_PFINFO_L3TAB (0x3U<<28)
-#define XEN_DOMCTL_PFINFO_L4TAB (0x4U<<28)
-#define XEN_DOMCTL_PFINFO_LTABTYPE_MASK (0x7U<<28)
-#define XEN_DOMCTL_PFINFO_LPINTAB (0x1U<<31)
-#define XEN_DOMCTL_PFINFO_XTAB (0xfU<<28) /* invalid page */
-#define XEN_DOMCTL_PFINFO_XALLOC (0xeU<<28) /* allocate-only page */
-#define XEN_DOMCTL_PFINFO_BROKEN (0xdU<<28) /* broken page */
-#define XEN_DOMCTL_PFINFO_LTAB_MASK (0xfU<<28)
-
-struct xen_domctl_getpageframeinfo {
- /* IN variables. */
- uint64_aligned_t gmfn; /* GMFN to query */
- /* OUT variables. */
- /* Is the page PINNED to a type? */
- uint32_t type; /* see above type defs */
-};
-typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t);
-
-
-/* XEN_DOMCTL_getpageframeinfo2 */
-struct xen_domctl_getpageframeinfo2 {
- /* IN variables. */
- uint64_aligned_t num;
- /* IN/OUT variables. */
- XEN_GUEST_HANDLE_64(uint32) array;
-};
-typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t);
-
-/* XEN_DOMCTL_getpageframeinfo3 */
-struct xen_domctl_getpageframeinfo3 {
- /* IN variables. */
- uint64_aligned_t num;
- /* IN/OUT variables. */
- XEN_GUEST_HANDLE_64(xen_pfn_t) array;
-};
-
-
-/*
- * Control shadow pagetables operation
- */
-/* XEN_DOMCTL_shadow_op */
-
-/* Disable shadow mode. */
-#define XEN_DOMCTL_SHADOW_OP_OFF 0
-
-/* Enable shadow mode (mode contains ORed XEN_DOMCTL_SHADOW_ENABLE_* flags). */
-#define XEN_DOMCTL_SHADOW_OP_ENABLE 32
-
-/* Log-dirty bitmap operations. */
- /* Return the bitmap and clean internal copy for next round. */
-#define XEN_DOMCTL_SHADOW_OP_CLEAN 11
- /* Return the bitmap but do not modify internal copy. */
-#define XEN_DOMCTL_SHADOW_OP_PEEK 12
-
-/* Memory allocation accessors. */
-#define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION 30
-#define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION 31
-
-/* Legacy enable operations. */
- /* Equiv. to ENABLE with no mode flags. */
-#define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST 1
- /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
-#define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY 2
- /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
-#define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE 3
-
-/* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */
- /*
- * Shadow pagetables are refcounted: guest does not use explicit mmu
- * operations nor write-protect its pagetables.
- */
-#define XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT (1 << 1)
- /*
- * Log pages in a bitmap as they are dirtied.
- * Used for live relocation to determine which pages must be re-sent.
- */
-#define XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
- /*
- * Automatically translate GPFNs into MFNs.
- */
-#define XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE (1 << 3)
- /*
- * Xen does not steal virtual address space from the guest.
- * Requires HVM support.
- */
-#define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL (1 << 4)
-
-struct xen_domctl_shadow_op_stats {
- uint32_t fault_count;
- uint32_t dirty_count;
-};
-typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t);
-
-struct xen_domctl_shadow_op {
- /* IN variables. */
- uint32_t op; /* XEN_DOMCTL_SHADOW_OP_* */
-
- /* OP_ENABLE */
- uint32_t mode; /* XEN_DOMCTL_SHADOW_ENABLE_* */
-
- /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */
- uint32_t mb; /* Shadow memory allocation in MB */
-
- /* OP_PEEK / OP_CLEAN */
- XEN_GUEST_HANDLE_64(uint8) dirty_bitmap;
- uint64_aligned_t pages; /* Size of buffer. Updated with actual size. */
- struct xen_domctl_shadow_op_stats stats;
-};
-typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t);
-
-
-/* XEN_DOMCTL_max_mem */
-struct xen_domctl_max_mem {
- /* IN variables. */
- uint64_aligned_t max_memkb;
-};
-typedef struct xen_domctl_max_mem xen_domctl_max_mem_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t);
-
-
-/* XEN_DOMCTL_setvcpucontext */
-/* XEN_DOMCTL_getvcpucontext */
-struct xen_domctl_vcpucontext {
- uint32_t vcpu; /* IN */
- XEN_GUEST_HANDLE_64(vcpu_guest_context_t) ctxt; /* IN/OUT */
-};
-typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t);
-
-
-/* XEN_DOMCTL_getvcpuinfo */
-struct xen_domctl_getvcpuinfo {
- /* IN variables. */
- uint32_t vcpu;
- /* OUT variables. */
- uint8_t online; /* currently online (not hotplugged)? */
- uint8_t blocked; /* blocked waiting for an event? */
- uint8_t running; /* currently scheduled on its CPU? */
- uint64_aligned_t cpu_time; /* total cpu time consumed (ns) */
- uint32_t cpu; /* current mapping */
-};
-typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t);
-
-
-/* Get/set the NUMA node(s) with which the guest has affinity with. */
-/* XEN_DOMCTL_setnodeaffinity */
-/* XEN_DOMCTL_getnodeaffinity */
-struct xen_domctl_nodeaffinity {
- struct xenctl_bitmap nodemap;/* IN */
-};
-typedef struct xen_domctl_nodeaffinity xen_domctl_nodeaffinity_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_nodeaffinity_t);
-
-
-/* Get/set which physical cpus a vcpu can execute on. */
-/* XEN_DOMCTL_setvcpuaffinity */
-/* XEN_DOMCTL_getvcpuaffinity */
-struct xen_domctl_vcpuaffinity {
- /* IN variables. */
- uint32_t vcpu;
- /* Set/get the hard affinity for vcpu */
-#define _XEN_VCPUAFFINITY_HARD 0
-#define XEN_VCPUAFFINITY_HARD (1U<<_XEN_VCPUAFFINITY_HARD)
- /* Set/get the soft affinity for vcpu */
-#define _XEN_VCPUAFFINITY_SOFT 1
-#define XEN_VCPUAFFINITY_SOFT (1U<<_XEN_VCPUAFFINITY_SOFT)
- uint32_t flags;
- /*
- * IN/OUT variables.
- *
- * Both are IN/OUT for XEN_DOMCTL_setvcpuaffinity, in which case they
- * contain effective hard or/and soft affinity. That is, upon successful
- * return, cpumap_soft, contains the intersection of the soft affinity,
- * hard affinity and the cpupool's online CPUs for the domain (if
- * XEN_VCPUAFFINITY_SOFT was set in flags). cpumap_hard contains the
- * intersection between hard affinity and the cpupool's online CPUs (if
- * XEN_VCPUAFFINITY_HARD was set in flags).
- *
- * Both are OUT-only for XEN_DOMCTL_getvcpuaffinity, in which case they
- * contain the plain hard and/or soft affinity masks that were set during
- * previous successful calls to XEN_DOMCTL_setvcpuaffinity (or the
- * default values), without intersecting or altering them in any way.
- */
- struct xenctl_bitmap cpumap_hard;
- struct xenctl_bitmap cpumap_soft;
-};
-typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t);
-
-
-/* XEN_DOMCTL_max_vcpus */
-struct xen_domctl_max_vcpus {
- uint32_t max; /* maximum number of vcpus */
-};
-typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
-
-
-/* XEN_DOMCTL_scheduler_op */
-/* Scheduler types. */
-#define XEN_SCHEDULER_SEDF 4
-#define XEN_SCHEDULER_CREDIT 5
-#define XEN_SCHEDULER_CREDIT2 6
-#define XEN_SCHEDULER_ARINC653 7
-#define XEN_SCHEDULER_RTDS 8
-
-/* Set or get info? */
-#define XEN_DOMCTL_SCHEDOP_putinfo 0
-#define XEN_DOMCTL_SCHEDOP_getinfo 1
-struct xen_domctl_scheduler_op {
- uint32_t sched_id; /* XEN_SCHEDULER_* */
- uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */
- union {
- struct xen_domctl_sched_sedf {
- uint64_aligned_t period;
- uint64_aligned_t slice;
- uint64_aligned_t latency;
- uint32_t extratime;
- uint32_t weight;
- } sedf;
- struct xen_domctl_sched_credit {
- uint16_t weight;
- uint16_t cap;
- } credit;
- struct xen_domctl_sched_credit2 {
- uint16_t weight;
- } credit2;
- struct xen_domctl_sched_rtds {
- uint32_t period;
- uint32_t budget;
- } rtds;
- } u;
-};
-typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t);
-
-
-/* XEN_DOMCTL_setdomainhandle */
-struct xen_domctl_setdomainhandle {
- xen_domain_handle_t handle;
-};
-typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t);
-
-
-/* XEN_DOMCTL_setdebugging */
-struct xen_domctl_setdebugging {
- uint8_t enable;
-};
-typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t);
-
-
-/* XEN_DOMCTL_irq_permission */
-struct xen_domctl_irq_permission {
- uint8_t pirq;
- uint8_t allow_access; /* flag to specify enable/disable of IRQ access */
-};
-typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t);
-
-
-/* XEN_DOMCTL_iomem_permission */
-struct xen_domctl_iomem_permission {
- uint64_aligned_t first_mfn;/* first page (physical page number) in range */
- uint64_aligned_t nr_mfns; /* number of pages in range (>0) */
- uint8_t allow_access; /* allow (!0) or deny (0) access to range? */
-};
-typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t);
-
-
-/* XEN_DOMCTL_ioport_permission */
-struct xen_domctl_ioport_permission {
- uint32_t first_port; /* first port int range */
- uint32_t nr_ports; /* size of port range */
- uint8_t allow_access; /* allow or deny access to range? */
-};
-typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t);
-
-
-/* XEN_DOMCTL_hypercall_init */
-struct xen_domctl_hypercall_init {
- uint64_aligned_t gmfn; /* GMFN to be initialised */
-};
-typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t);
-
-
-/* XEN_DOMCTL_settimeoffset */
-struct xen_domctl_settimeoffset {
- int32_t time_offset_seconds; /* applied to domain wallclock time */
-};
-typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
-
-/* XEN_DOMCTL_gethvmcontext */
-/* XEN_DOMCTL_sethvmcontext */
-typedef struct xen_domctl_hvmcontext {
- uint32_t size; /* IN/OUT: size of buffer / bytes filled */
- XEN_GUEST_HANDLE_64(uint8) buffer; /* IN/OUT: data, or call
- * gethvmcontext with NULL
- * buffer to get size req'd */
-} xen_domctl_hvmcontext_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
-
-
-/* XEN_DOMCTL_set_address_size */
-/* XEN_DOMCTL_get_address_size */
-typedef struct xen_domctl_address_size {
- uint32_t size;
-} xen_domctl_address_size_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_address_size_t);
-
-
-/* XEN_DOMCTL_sendtrigger */
-#define XEN_DOMCTL_SENDTRIGGER_NMI 0
-#define XEN_DOMCTL_SENDTRIGGER_RESET 1
-#define XEN_DOMCTL_SENDTRIGGER_INIT 2
-#define XEN_DOMCTL_SENDTRIGGER_POWER 3
-#define XEN_DOMCTL_SENDTRIGGER_SLEEP 4
-struct xen_domctl_sendtrigger {
- uint32_t trigger; /* IN */
- uint32_t vcpu; /* IN */
-};
-typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
-
-
-/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
-/* XEN_DOMCTL_assign_device */
-/* XEN_DOMCTL_test_assign_device */
-/* XEN_DOMCTL_deassign_device */
-struct xen_domctl_assign_device {
- uint32_t machine_sbdf; /* machine PCI ID of assigned device */
-};
-typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
-
-/* Retrieve sibling devices infomation of machine_sbdf */
-/* XEN_DOMCTL_get_device_group */
-struct xen_domctl_get_device_group {
- uint32_t machine_sbdf; /* IN */
- uint32_t max_sdevs; /* IN */
- uint32_t num_sdevs; /* OUT */
- XEN_GUEST_HANDLE_64(uint32) sdev_array; /* OUT */
-};
-typedef struct xen_domctl_get_device_group xen_domctl_get_device_group_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_get_device_group_t);
-
-/* Pass-through interrupts: bind real irq -> hvm devfn. */
-/* XEN_DOMCTL_bind_pt_irq */
-/* XEN_DOMCTL_unbind_pt_irq */
-typedef enum pt_irq_type_e {
- PT_IRQ_TYPE_PCI,
- PT_IRQ_TYPE_ISA,
- PT_IRQ_TYPE_MSI,
- PT_IRQ_TYPE_MSI_TRANSLATE,
-} pt_irq_type_t;
-struct xen_domctl_bind_pt_irq {
- uint32_t machine_irq;
- pt_irq_type_t irq_type;
- uint32_t hvm_domid;
-
- union {
- struct {
- uint8_t isa_irq;
- } isa;
- struct {
- uint8_t bus;
- uint8_t device;
- uint8_t intx;
- } pci;
- struct {
- uint8_t gvec;
- uint32_t gflags;
- uint64_aligned_t gtable;
- } msi;
- } u;
-};
-typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t);
-
-
-/* Bind machine I/O address range -> HVM address range. */
-/* XEN_DOMCTL_memory_mapping */
-#define DPCI_ADD_MAPPING 1
-#define DPCI_REMOVE_MAPPING 0
-struct xen_domctl_memory_mapping {
- uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
- uint64_aligned_t first_mfn; /* first page (machine page) in range */
- uint64_aligned_t nr_mfns; /* number of pages in range (>0) */
- uint32_t add_mapping; /* add or remove mapping */
- uint32_t padding; /* padding for 64-bit aligned structure */
-};
-typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t);
-
-
-/* Bind machine I/O port range -> HVM I/O port range. */
-/* XEN_DOMCTL_ioport_mapping */
-struct xen_domctl_ioport_mapping {
- uint32_t first_gport; /* first guest IO port*/
- uint32_t first_mport; /* first machine IO port */
- uint32_t nr_ports; /* size of port range */
- uint32_t add_mapping; /* add or remove mapping */
-};
-typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t);
-
-
-/*
- * Pin caching type of RAM space for x86 HVM domU.
- */
-/* XEN_DOMCTL_pin_mem_cacheattr */
-/* Caching types: these happen to be the same as x86 MTRR/PAT type codes. */
-#define XEN_DOMCTL_MEM_CACHEATTR_UC 0
-#define XEN_DOMCTL_MEM_CACHEATTR_WC 1
-#define XEN_DOMCTL_MEM_CACHEATTR_WT 4
-#define XEN_DOMCTL_MEM_CACHEATTR_WP 5
-#define XEN_DOMCTL_MEM_CACHEATTR_WB 6
-#define XEN_DOMCTL_MEM_CACHEATTR_UCM 7
-#define XEN_DOMCTL_DELETE_MEM_CACHEATTR (~(uint32_t)0)
-struct xen_domctl_pin_mem_cacheattr {
- uint64_aligned_t start, end;
- uint32_t type; /* XEN_DOMCTL_MEM_CACHEATTR_* */
-};
-typedef struct xen_domctl_pin_mem_cacheattr xen_domctl_pin_mem_cacheattr_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_pin_mem_cacheattr_t);
-
-
-/* XEN_DOMCTL_set_ext_vcpucontext */
-/* XEN_DOMCTL_get_ext_vcpucontext */
-struct xen_domctl_ext_vcpucontext {
- /* IN: VCPU that this call applies to. */
- uint32_t vcpu;
- /*
- * SET: Size of struct (IN)
- * GET: Size of struct (OUT, up to 128 bytes)
- */
- uint32_t size;
-#if defined(__i386__) || defined(__x86_64__)
- /* SYSCALL from 32-bit mode and SYSENTER callback information. */
- /* NB. SYSCALL from 64-bit mode is contained in vcpu_guest_context_t */
- uint64_aligned_t syscall32_callback_eip;
- uint64_aligned_t sysenter_callback_eip;
- uint16_t syscall32_callback_cs;
- uint16_t sysenter_callback_cs;
- uint8_t syscall32_disables_events;
- uint8_t sysenter_disables_events;
-#if defined(__GNUC__)
- union {
- uint64_aligned_t mcg_cap;
- struct hvm_vmce_vcpu vmce;
- };
-#else
- struct hvm_vmce_vcpu vmce;
-#endif
-#endif
-};
-typedef struct xen_domctl_ext_vcpucontext xen_domctl_ext_vcpucontext_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_ext_vcpucontext_t);
-
-/*
- * Set the target domain for a domain
- */
-/* XEN_DOMCTL_set_target */
-struct xen_domctl_set_target {
- domid_t target;
-};
-typedef struct xen_domctl_set_target xen_domctl_set_target_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t);
-
-#if defined(__i386__) || defined(__x86_64__)
-# define XEN_CPUID_INPUT_UNUSED 0xFFFFFFFF
-/* XEN_DOMCTL_set_cpuid */
-struct xen_domctl_cpuid {
- uint32_t input[2];
- uint32_t eax;
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
-};
-typedef struct xen_domctl_cpuid xen_domctl_cpuid_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpuid_t);
-#endif
-
-/*
- * Arranges that if the domain suspends (specifically, if it shuts
- * down with code SHUTDOWN_suspend), this event channel will be
- * notified.
- *
- * This is _instead of_ the usual notification to the global
- * VIRQ_DOM_EXC. (In most systems that pirq is owned by xenstored.)
- *
- * Only one subscription per domain is possible. Last subscriber
- * wins; others are silently displaced.
- *
- * NB that contrary to the rather general name, it only applies to
- * domain shutdown with code suspend. Shutdown for other reasons
- * (including crash), and domain death, are notified to VIRQ_DOM_EXC
- * regardless.
- */
-/* XEN_DOMCTL_subscribe */
-struct xen_domctl_subscribe {
- uint32_t port; /* IN */
-};
-typedef struct xen_domctl_subscribe xen_domctl_subscribe_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_subscribe_t);
-
-/*
- * Define the maximum machine address size which should be allocated
- * to a guest.
- */
-/* XEN_DOMCTL_set_machine_address_size */
-/* XEN_DOMCTL_get_machine_address_size */
-
-/*
- * Do not inject spurious page faults into this domain.
- */
-/* XEN_DOMCTL_suppress_spurious_page_faults */
-
-/* XEN_DOMCTL_debug_op */
-#define XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF 0
-#define XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON 1
-struct xen_domctl_debug_op {
- uint32_t op; /* IN */
- uint32_t vcpu; /* IN */
-};
-typedef struct xen_domctl_debug_op xen_domctl_debug_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t);
-
-/*
- * Request a particular record from the HVM context
- */
-/* XEN_DOMCTL_gethvmcontext_partial */
-typedef struct xen_domctl_hvmcontext_partial {
- uint32_t type; /* IN: Type of record required */
- uint32_t instance; /* IN: Instance of that type */
- XEN_GUEST_HANDLE_64(uint8) buffer; /* OUT: buffer to write record into */
-} xen_domctl_hvmcontext_partial_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t);
-
-/* XEN_DOMCTL_disable_migrate */
-typedef struct xen_domctl_disable_migrate {
- uint32_t disable; /* IN: 1: disable migration and restore */
-} xen_domctl_disable_migrate_t;
-
-
-/* XEN_DOMCTL_gettscinfo */
-/* XEN_DOMCTL_settscinfo */
-struct xen_guest_tsc_info {
- uint32_t tsc_mode;
- uint32_t gtsc_khz;
- uint32_t incarnation;
- uint32_t pad;
- uint64_aligned_t elapsed_nsec;
-};
-typedef struct xen_guest_tsc_info xen_guest_tsc_info_t;
-DEFINE_XEN_GUEST_HANDLE(xen_guest_tsc_info_t);
-typedef struct xen_domctl_tsc_info {
- XEN_GUEST_HANDLE_64(xen_guest_tsc_info_t) out_info; /* OUT */
- xen_guest_tsc_info_t info; /* IN */
-} xen_domctl_tsc_info_t;
-
-/* XEN_DOMCTL_gdbsx_guestmemio guest mem io */
-struct xen_domctl_gdbsx_memio {
- /* IN */
- uint64_aligned_t pgd3val;/* optional: init_mm.pgd[3] value */
- uint64_aligned_t gva; /* guest virtual address */
- uint64_aligned_t uva; /* user buffer virtual address */
- uint32_t len; /* number of bytes to read/write */
- uint8_t gwr; /* 0 = read from guest. 1 = write to guest */
- /* OUT */
- uint32_t remain; /* bytes remaining to be copied */
-};
-
-/* XEN_DOMCTL_gdbsx_pausevcpu */
-/* XEN_DOMCTL_gdbsx_unpausevcpu */
-struct xen_domctl_gdbsx_pauseunp_vcpu { /* pause/unpause a vcpu */
- uint32_t vcpu; /* which vcpu */
-};
-
-/* XEN_DOMCTL_gdbsx_domstatus */
-struct xen_domctl_gdbsx_domstatus {
- /* OUT */
- uint8_t paused; /* is the domain paused */
- uint32_t vcpu_id; /* any vcpu in an event? */
- uint32_t vcpu_ev; /* if yes, what event? */
-};
-
-/*
- * Memory event operations
- */
-
-/* XEN_DOMCTL_mem_event_op */
-
-/*
- * Domain memory paging
- * Page memory in and out.
- * Domctl interface to set up and tear down the
- * pager<->hypervisor interface. Use XENMEM_paging_op*
- * to perform per-page operations.
- *
- * The XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE domctl returns several
- * non-standard error codes to indicate why paging could not be enabled:
- * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest
- * EMLINK - guest has iommu passthrough enabled
- * EXDEV - guest has PoD enabled
- * EBUSY - guest has or had paging enabled, ring buffer still active
- */
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING 1
-
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE 0
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE 1
-
-/*
- * Access permissions.
- *
- * As with paging, use the domctl for teardown/setup of the
- * helper<->hypervisor interface.
- *
- * There are HVM hypercalls to set the per-page access permissions of every
- * page in a domain. When one of these permissions--independent, read,
- * write, and execute--is violated, the VCPU is paused and a memory event
- * is sent with what happened. (See public/mem_event.h) .
- *
- * The memory event handler can then resume the VCPU and redo the access
- * with a XENMEM_access_op_resume hypercall.
- *
- * The XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE domctl returns several
- * non-standard error codes to indicate why access could not be enabled:
- * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest
- * EBUSY - guest has or had access enabled, ring buffer still active
- */
-#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS 2
-
-#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE 0
-#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE 1
-#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE_INTROSPECTION 2
-
-/*
- * Sharing ENOMEM helper.
- *
- * As with paging, use the domctl for teardown/setup of the
- * helper<->hypervisor interface.
- *
- * If setup, this ring is used to communicate failed allocations
- * in the unshare path. XENMEM_sharing_op_resume is used to wake up
- * vcpus that could not unshare.
- *
- * Note that shring can be turned on (as per the domctl below)
- * *without* this ring being setup.
- */
-#define XEN_DOMCTL_MEM_EVENT_OP_SHARING 3
-
-#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE 0
-#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DISABLE 1
-
-/* Use for teardown/setup of helper<->hypervisor interface for paging,
- * access and sharing.*/
-struct xen_domctl_mem_event_op {
- uint32_t op; /* XEN_DOMCTL_MEM_EVENT_OP_*_* */
- uint32_t mode; /* XEN_DOMCTL_MEM_EVENT_OP_* */
-
- uint32_t port; /* OUT: event channel for ring */
-};
-typedef struct xen_domctl_mem_event_op xen_domctl_mem_event_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_event_op_t);
-
-/*
- * Memory sharing operations
- */
-/* XEN_DOMCTL_mem_sharing_op.
- * The CONTROL sub-domctl is used for bringup/teardown. */
-#define XEN_DOMCTL_MEM_SHARING_CONTROL 0
-
-struct xen_domctl_mem_sharing_op {
- uint8_t op; /* XEN_DOMCTL_MEM_SHARING_* */
-
- union {
- uint8_t enable; /* CONTROL */
- } u;
-};
-typedef struct xen_domctl_mem_sharing_op xen_domctl_mem_sharing_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_sharing_op_t);
-
-struct xen_domctl_audit_p2m {
- /* OUT error counts */
- uint64_t orphans;
- uint64_t m2p_bad;
- uint64_t p2m_bad;
-};
-typedef struct xen_domctl_audit_p2m xen_domctl_audit_p2m_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_audit_p2m_t);
-
-struct xen_domctl_set_virq_handler {
- uint32_t virq; /* IN */
-};
-typedef struct xen_domctl_set_virq_handler xen_domctl_set_virq_handler_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_virq_handler_t);
-
-#if defined(__i386__) || defined(__x86_64__)
-/* XEN_DOMCTL_setvcpuextstate */
-/* XEN_DOMCTL_getvcpuextstate */
-struct xen_domctl_vcpuextstate {
- /* IN: VCPU that this call applies to. */
- uint32_t vcpu;
- /*
- * SET: Ignored.
- * GET: xfeature support mask of struct (IN/OUT)
- * xfeature mask is served as identifications of the saving format
- * so that compatible CPUs can have a check on format to decide
- * whether it can restore.
- */
- uint64_aligned_t xfeature_mask;
- /*
- * SET: Size of struct (IN)
- * GET: Size of struct (IN/OUT)
- */
- uint64_aligned_t size;
- XEN_GUEST_HANDLE_64(uint64) buffer;
-};
-typedef struct xen_domctl_vcpuextstate xen_domctl_vcpuextstate_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuextstate_t);
-#endif
-
-/* XEN_DOMCTL_set_access_required: sets whether a memory event listener
- * must be present to handle page access events: if false, the page
- * access will revert to full permissions if no one is listening;
- * */
-struct xen_domctl_set_access_required {
- uint8_t access_required;
-};
-typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
-
-struct xen_domctl_set_broken_page_p2m {
- uint64_aligned_t pfn;
-};
-typedef struct xen_domctl_set_broken_page_p2m xen_domctl_set_broken_page_p2m_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_broken_page_p2m_t);
-
-/*
- * XEN_DOMCTL_set_max_evtchn: sets the maximum event channel port
- * number the guest may use. Use this limit the amount of resources
- * (global mapping space, xenheap) a guest may use for event channels.
- */
-struct xen_domctl_set_max_evtchn {
- uint32_t max_port;
-};
-typedef struct xen_domctl_set_max_evtchn xen_domctl_set_max_evtchn_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_max_evtchn_t);
-
-/*
- * ARM: Clean and invalidate caches associated with given region of
- * guest memory.
- */
-struct xen_domctl_cacheflush {
- /* IN: page range to flush. */
- xen_pfn_t start_pfn, nr_pfns;
-};
-typedef struct xen_domctl_cacheflush xen_domctl_cacheflush_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_cacheflush_t);
-
-#if defined(__i386__) || defined(__x86_64__)
-struct xen_domctl_vcpu_msr {
- uint32_t index;
- uint32_t reserved;
- uint64_aligned_t value;
-};
-typedef struct xen_domctl_vcpu_msr xen_domctl_vcpu_msr_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpu_msr_t);
-
-/*
- * XEN_DOMCTL_set_vcpu_msrs / XEN_DOMCTL_get_vcpu_msrs.
- *
- * Input:
- * - A NULL 'msrs' guest handle is a request for the maximum 'msr_count'.
- * - Otherwise, 'msr_count' is the number of entries in 'msrs'.
- *
- * Output for get:
- * - If 'msr_count' is less than the number Xen needs to write, -ENOBUFS shall
- * be returned and 'msr_count' updated to reflect the intended number.
- * - On success, 'msr_count' shall indicate the number of MSRs written, which
- * may be less than the maximum if some are not currently used by the vcpu.
- *
- * Output for set:
- * - If Xen encounters an error with a specific MSR, -EINVAL shall be returned
- * and 'msr_count' shall be set to the offending index, to aid debugging.
- */
-struct xen_domctl_vcpu_msrs {
- uint32_t vcpu; /* IN */
- uint32_t msr_count; /* IN/OUT */
- XEN_GUEST_HANDLE_64(xen_domctl_vcpu_msr_t) msrs; /* IN/OUT */
-};
-typedef struct xen_domctl_vcpu_msrs xen_domctl_vcpu_msrs_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpu_msrs_t);
-#endif
-
-/*
- * Use in XEN_DOMCTL_setvnumainfo to set
- * vNUMA domain topology.
- */
-struct xen_domctl_vnuma {
- uint32_t nr_vnodes;
- uint32_t nr_vmemranges;
- uint32_t nr_vcpus;
- uint32_t pad;
- XEN_GUEST_HANDLE_64(uint) vdistance;
- XEN_GUEST_HANDLE_64(uint) vcpu_to_vnode;
-
- /*
- * vnodes to physical NUMA nodes mask.
- * This kept on per-domain basis for
- * interested consumers, such as numa aware ballooning.
- */
- XEN_GUEST_HANDLE_64(uint) vnode_to_pnode;
-
- /*
- * memory rages for each vNUMA node
- */
- XEN_GUEST_HANDLE_64(xen_vmemrange_t) vmemrange;
-};
-typedef struct xen_domctl_vnuma xen_domctl_vnuma_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_vnuma_t);
-
-struct xen_domctl_psr_cmt_op {
-#define XEN_DOMCTL_PSR_CMT_OP_DETACH 0
-#define XEN_DOMCTL_PSR_CMT_OP_ATTACH 1
-#define XEN_DOMCTL_PSR_CMT_OP_QUERY_RMID 2
- uint32_t cmd;
- uint32_t data;
-};
-typedef struct xen_domctl_psr_cmt_op xen_domctl_psr_cmt_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t);
-
-struct xen_domctl {
- uint32_t cmd;
-#define XEN_DOMCTL_createdomain 1
-#define XEN_DOMCTL_destroydomain 2
-#define XEN_DOMCTL_pausedomain 3
-#define XEN_DOMCTL_unpausedomain 4
-#define XEN_DOMCTL_getdomaininfo 5
-#define XEN_DOMCTL_getmemlist 6
-#define XEN_DOMCTL_getpageframeinfo 7
-#define XEN_DOMCTL_getpageframeinfo2 8
-#define XEN_DOMCTL_setvcpuaffinity 9
-#define XEN_DOMCTL_shadow_op 10
-#define XEN_DOMCTL_max_mem 11
-#define XEN_DOMCTL_setvcpucontext 12
-#define XEN_DOMCTL_getvcpucontext 13
-#define XEN_DOMCTL_getvcpuinfo 14
-#define XEN_DOMCTL_max_vcpus 15
-#define XEN_DOMCTL_scheduler_op 16
-#define XEN_DOMCTL_setdomainhandle 17
-#define XEN_DOMCTL_setdebugging 18
-#define XEN_DOMCTL_irq_permission 19
-#define XEN_DOMCTL_iomem_permission 20
-#define XEN_DOMCTL_ioport_permission 21
-#define XEN_DOMCTL_hypercall_init 22
-#define XEN_DOMCTL_arch_setup 23 /* Obsolete IA64 only */
-#define XEN_DOMCTL_settimeoffset 24
-#define XEN_DOMCTL_getvcpuaffinity 25
-#define XEN_DOMCTL_real_mode_area 26 /* Obsolete PPC only */
-#define XEN_DOMCTL_resumedomain 27
-#define XEN_DOMCTL_sendtrigger 28
-#define XEN_DOMCTL_subscribe 29
-#define XEN_DOMCTL_gethvmcontext 33
-#define XEN_DOMCTL_sethvmcontext 34
-#define XEN_DOMCTL_set_address_size 35
-#define XEN_DOMCTL_get_address_size 36
-#define XEN_DOMCTL_assign_device 37
-#define XEN_DOMCTL_bind_pt_irq 38
-#define XEN_DOMCTL_memory_mapping 39
-#define XEN_DOMCTL_ioport_mapping 40
-#define XEN_DOMCTL_pin_mem_cacheattr 41
-#define XEN_DOMCTL_set_ext_vcpucontext 42
-#define XEN_DOMCTL_get_ext_vcpucontext 43
-#define XEN_DOMCTL_set_opt_feature 44 /* Obsolete IA64 only */
-#define XEN_DOMCTL_test_assign_device 45
-#define XEN_DOMCTL_set_target 46
-#define XEN_DOMCTL_deassign_device 47
-#define XEN_DOMCTL_unbind_pt_irq 48
-#define XEN_DOMCTL_set_cpuid 49
-#define XEN_DOMCTL_get_device_group 50
-#define XEN_DOMCTL_set_machine_address_size 51
-#define XEN_DOMCTL_get_machine_address_size 52
-#define XEN_DOMCTL_suppress_spurious_page_faults 53
-#define XEN_DOMCTL_debug_op 54
-#define XEN_DOMCTL_gethvmcontext_partial 55
-#define XEN_DOMCTL_mem_event_op 56
-#define XEN_DOMCTL_mem_sharing_op 57
-#define XEN_DOMCTL_disable_migrate 58
-#define XEN_DOMCTL_gettscinfo 59
-#define XEN_DOMCTL_settscinfo 60
-#define XEN_DOMCTL_getpageframeinfo3 61
-#define XEN_DOMCTL_setvcpuextstate 62
-#define XEN_DOMCTL_getvcpuextstate 63
-#define XEN_DOMCTL_set_access_required 64
-#define XEN_DOMCTL_audit_p2m 65
-#define XEN_DOMCTL_set_virq_handler 66
-#define XEN_DOMCTL_set_broken_page_p2m 67
-#define XEN_DOMCTL_setnodeaffinity 68
-#define XEN_DOMCTL_getnodeaffinity 69
-#define XEN_DOMCTL_set_max_evtchn 70
-#define XEN_DOMCTL_cacheflush 71
-#define XEN_DOMCTL_get_vcpu_msrs 72
-#define XEN_DOMCTL_set_vcpu_msrs 73
-#define XEN_DOMCTL_setvnumainfo 74
-#define XEN_DOMCTL_psr_cmt_op 75
-#define XEN_DOMCTL_arm_configure_domain 76
-#define XEN_DOMCTL_gdbsx_guestmemio 1000
-#define XEN_DOMCTL_gdbsx_pausevcpu 1001
-#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
-#define XEN_DOMCTL_gdbsx_domstatus 1003
- uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
- domid_t domain;
- union {
- struct xen_domctl_createdomain createdomain;
-#if defined(__arm__) || defined(__aarch64__)
- struct xen_domctl_arm_configuredomain configuredomain;
-#endif
- struct xen_domctl_getdomaininfo getdomaininfo;
- struct xen_domctl_getmemlist getmemlist;
- struct xen_domctl_getpageframeinfo getpageframeinfo;
- struct xen_domctl_getpageframeinfo2 getpageframeinfo2;
- struct xen_domctl_getpageframeinfo3 getpageframeinfo3;
- struct xen_domctl_nodeaffinity nodeaffinity;
- struct xen_domctl_vcpuaffinity vcpuaffinity;
- struct xen_domctl_shadow_op shadow_op;
- struct xen_domctl_max_mem max_mem;
- struct xen_domctl_vcpucontext vcpucontext;
- struct xen_domctl_getvcpuinfo getvcpuinfo;
- struct xen_domctl_max_vcpus max_vcpus;
- struct xen_domctl_scheduler_op scheduler_op;
- struct xen_domctl_setdomainhandle setdomainhandle;
- struct xen_domctl_setdebugging setdebugging;
- struct xen_domctl_irq_permission irq_permission;
- struct xen_domctl_iomem_permission iomem_permission;
- struct xen_domctl_ioport_permission ioport_permission;
- struct xen_domctl_hypercall_init hypercall_init;
- struct xen_domctl_settimeoffset settimeoffset;
- struct xen_domctl_disable_migrate disable_migrate;
- struct xen_domctl_tsc_info tsc_info;
- struct xen_domctl_hvmcontext hvmcontext;
- struct xen_domctl_hvmcontext_partial hvmcontext_partial;
- struct xen_domctl_address_size address_size;
- struct xen_domctl_sendtrigger sendtrigger;
- struct xen_domctl_get_device_group get_device_group;
- struct xen_domctl_assign_device assign_device;
- struct xen_domctl_bind_pt_irq bind_pt_irq;
- struct xen_domctl_memory_mapping memory_mapping;
- struct xen_domctl_ioport_mapping ioport_mapping;
- struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
- struct xen_domctl_ext_vcpucontext ext_vcpucontext;
- struct xen_domctl_set_target set_target;
- struct xen_domctl_subscribe subscribe;
- struct xen_domctl_debug_op debug_op;
- struct xen_domctl_mem_event_op mem_event_op;
- struct xen_domctl_mem_sharing_op mem_sharing_op;
-#if defined(__i386__) || defined(__x86_64__)
- struct xen_domctl_cpuid cpuid;
- struct xen_domctl_vcpuextstate vcpuextstate;
- struct xen_domctl_vcpu_msrs vcpu_msrs;
-#endif
- struct xen_domctl_set_access_required access_required;
- struct xen_domctl_audit_p2m audit_p2m;
- struct xen_domctl_set_virq_handler set_virq_handler;
- struct xen_domctl_set_max_evtchn set_max_evtchn;
- struct xen_domctl_gdbsx_memio gdbsx_guest_memio;
- struct xen_domctl_set_broken_page_p2m set_broken_page_p2m;
- struct xen_domctl_cacheflush cacheflush;
- struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
- struct xen_domctl_gdbsx_domstatus gdbsx_domstatus;
- struct xen_domctl_vnuma vnuma;
- struct xen_domctl_psr_cmt_op psr_cmt_op;
- uint8_t pad[128];
- } u;
-};
-typedef struct xen_domctl xen_domctl_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
-
-#endif /* __XEN_PUBLIC_DOMCTL_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * elfnote.h
- *
- * Definitions used for the Xen ELF notes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2006, Ian Campbell, XenSource Ltd.
- */
-
-#ifndef __XEN_PUBLIC_ELFNOTE_H__
-#define __XEN_PUBLIC_ELFNOTE_H__
-
-/*
- * `incontents 200 elfnotes ELF notes
- *
- * The notes should live in a PT_NOTE segment and have "Xen" in the
- * name field.
- *
- * Numeric types are either 4 or 8 bytes depending on the content of
- * the desc field.
- *
- * LEGACY indicated the fields in the legacy __xen_guest string which
- * this a note type replaces.
- *
- * String values (for non-legacy) are NULL terminated ASCII, also known
- * as ASCIZ type.
- */
-
-/*
- * NAME=VALUE pair (string).
- */
-#define XEN_ELFNOTE_INFO 0
-
-/*
- * The virtual address of the entry point (numeric).
- *
- * LEGACY: VIRT_ENTRY
- */
-#define XEN_ELFNOTE_ENTRY 1
-
-/* The virtual address of the hypercall transfer page (numeric).
- *
- * LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page
- * number not a virtual address)
- */
-#define XEN_ELFNOTE_HYPERCALL_PAGE 2
-
-/* The virtual address where the kernel image should be mapped (numeric).
- *
- * Defaults to 0.
- *
- * LEGACY: VIRT_BASE
- */
-#define XEN_ELFNOTE_VIRT_BASE 3
-
-/*
- * The offset of the ELF paddr field from the actual required
- * pseudo-physical address (numeric).
- *
- * This is used to maintain backwards compatibility with older kernels
- * which wrote __PAGE_OFFSET into that field. This field defaults to 0
- * if not present.
- *
- * LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE)
- */
-#define XEN_ELFNOTE_PADDR_OFFSET 4
-
-/*
- * The version of Xen that we work with (string).
- *
- * LEGACY: XEN_VER
- */
-#define XEN_ELFNOTE_XEN_VERSION 5
-
-/*
- * The name of the guest operating system (string).
- *
- * LEGACY: GUEST_OS
- */
-#define XEN_ELFNOTE_GUEST_OS 6
-
-/*
- * The version of the guest operating system (string).
- *
- * LEGACY: GUEST_VER
- */
-#define XEN_ELFNOTE_GUEST_VERSION 7
-
-/*
- * The loader type (string).
- *
- * LEGACY: LOADER
- */
-#define XEN_ELFNOTE_LOADER 8
-
-/*
- * The kernel supports PAE (x86/32 only, string = "yes", "no" or
- * "bimodal").
- *
- * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting
- * may be given as "yes,bimodal" which will cause older Xen to treat
- * this kernel as PAE.
- *
- * LEGACY: PAE (n.b. The legacy interface included a provision to
- * indicate 'extended-cr3' support allowing L3 page tables to be
- * placed above 4G. It is assumed that any kernel new enough to use
- * these ELF notes will include this and therefore "yes" here is
- * equivalent to "yes[entended-cr3]" in the __xen_guest interface.
- */
-#define XEN_ELFNOTE_PAE_MODE 9
-
-/*
- * The features supported/required by this kernel (string).
- *
- * The string must consist of a list of feature names (as given in
- * features.h, without the "XENFEAT_" prefix) separated by '|'
- * characters. If a feature is required for the kernel to function
- * then the feature name must be preceded by a '!' character.
- *
- * LEGACY: FEATURES
- */
-#define XEN_ELFNOTE_FEATURES 10
-
-/*
- * The kernel requires the symbol table to be loaded (string = "yes" or "no")
- * LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence
- * of this string as a boolean flag rather than requiring "yes" or
- * "no".
- */
-#define XEN_ELFNOTE_BSD_SYMTAB 11
-
-/*
- * The lowest address the hypervisor hole can begin at (numeric).
- *
- * This must not be set higher than HYPERVISOR_VIRT_START. Its presence
- * also indicates to the hypervisor that the kernel can deal with the
- * hole starting at a higher address.
- */
-#define XEN_ELFNOTE_HV_START_LOW 12
-
-/*
- * List of maddr_t-sized mask/value pairs describing how to recognize
- * (non-present) L1 page table entries carrying valid MFNs (numeric).
- */
-#define XEN_ELFNOTE_L1_MFN_VALID 13
-
-/*
- * Whether or not the guest supports cooperative suspend cancellation.
- * This is a numeric value.
- *
- * Default is 0
- */
-#define XEN_ELFNOTE_SUSPEND_CANCEL 14
-
-/*
- * The (non-default) location the initial phys-to-machine map should be
- * placed at by the hypervisor (Dom0) or the tools (DomU).
- * The kernel must be prepared for this mapping to be established using
- * large pages, despite such otherwise not being available to guests.
- * The kernel must also be able to handle the page table pages used for
- * this mapping not being accessible through the initial mapping.
- * (Only x86-64 supports this at present.)
- */
-#define XEN_ELFNOTE_INIT_P2M 15
-
-/*
- * Whether or not the guest can deal with being passed an initrd not
- * mapped through its initial page tables.
- */
-#define XEN_ELFNOTE_MOD_START_PFN 16
-
-/*
- * The features supported by this kernel (numeric).
- *
- * Other than XEN_ELFNOTE_FEATURES on pre-4.2 Xen, this note allows a
- * kernel to specify support for features that older hypervisors don't
- * know about. The set of features 4.2 and newer hypervisors will
- * consider supported by the kernel is the combination of the sets
- * specified through this and the string note.
- *
- * LEGACY: FEATURES
- */
-#define XEN_ELFNOTE_SUPPORTED_FEATURES 17
-
-/*
- * The number of the highest elfnote defined.
- */
-#define XEN_ELFNOTE_MAX XEN_ELFNOTE_SUPPORTED_FEATURES
-
-/*
- * System information exported through crash notes.
- *
- * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO
- * note in case of a system crash. This note will contain various
- * information about the system, see xen/include/xen/elfcore.h.
- */
-#define XEN_ELFNOTE_CRASH_INFO 0x1000001
-
-/*
- * System registers exported through crash notes.
- *
- * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS
- * note per cpu in case of a system crash. This note is architecture
- * specific and will contain registers not saved in the "CORE" note.
- * See xen/include/xen/elfcore.h for more information.
- */
-#define XEN_ELFNOTE_CRASH_REGS 0x1000002
-
-
-/*
- * xen dump-core none note.
- * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE
- * in its dump file to indicate that the file is xen dump-core
- * file. This note doesn't have any other information.
- * See tools/libxc/xc_core.h for more information.
- */
-#define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000
-
-/*
- * xen dump-core header note.
- * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER
- * in its dump file.
- * See tools/libxc/xc_core.h for more information.
- */
-#define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001
-
-/*
- * xen dump-core xen version note.
- * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION
- * in its dump file. It contains the xen version obtained via the
- * XENVER hypercall.
- * See tools/libxc/xc_core.h for more information.
- */
-#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002
-
-/*
- * xen dump-core format version note.
- * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION
- * in its dump file. It contains a format version identifier.
- * See tools/libxc/xc_core.h for more information.
- */
-#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003
-
-#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * event_channel.h
- *
- * Event channels between domains.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2003-2004, K A Fraser.
- */
-
-#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
-#define __XEN_PUBLIC_EVENT_CHANNEL_H__
-
-#include "xen.h"
-
-/*
- * `incontents 150 evtchn Event Channels
- *
- * Event channels are the basic primitive provided by Xen for event
- * notifications. An event is the Xen equivalent of a hardware
- * interrupt. They essentially store one bit of information, the event
- * of interest is signalled by transitioning this bit from 0 to 1.
- *
- * Notifications are received by a guest via an upcall from Xen,
- * indicating when an event arrives (setting the bit). Further
- * notifications are masked until the bit is cleared again (therefore,
- * guests must check the value of the bit after re-enabling event
- * delivery to ensure no missed notifications).
- *
- * Event notifications can be masked by setting a flag; this is
- * equivalent to disabling interrupts and can be used to ensure
- * atomicity of certain operations in the guest kernel.
- *
- * Event channels are represented by the evtchn_* fields in
- * struct shared_info and struct vcpu_info.
- */
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_event_channel_op(enum event_channel_op cmd, void *args)
- * `
- * @cmd == EVTCHNOP_* (event-channel operation).
- * @args == struct evtchn_* Operation-specific extra arguments (NULL if none).
- */
-
-/* ` enum event_channel_op { // EVTCHNOP_* => struct evtchn_* */
-#define EVTCHNOP_bind_interdomain 0
-#define EVTCHNOP_bind_virq 1
-#define EVTCHNOP_bind_pirq 2
-#define EVTCHNOP_close 3
-#define EVTCHNOP_send 4
-#define EVTCHNOP_status 5
-#define EVTCHNOP_alloc_unbound 6
-#define EVTCHNOP_bind_ipi 7
-#define EVTCHNOP_bind_vcpu 8
-#define EVTCHNOP_unmask 9
-#define EVTCHNOP_reset 10
-#define EVTCHNOP_init_control 11
-#define EVTCHNOP_expand_array 12
-#define EVTCHNOP_set_priority 13
-/* ` } */
-
-typedef uint32_t evtchn_port_t;
-DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
-
-/*
- * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
- * accepting interdomain bindings from domain <remote_dom>. A fresh port
- * is allocated in <dom> and returned as <port>.
- * NOTES:
- * 1. If the caller is unprivileged then <dom> must be DOMID_SELF.
- * 2. <rdom> may be DOMID_SELF, allowing loopback connections.
- */
-struct evtchn_alloc_unbound {
- /* IN parameters */
- domid_t dom, remote_dom;
- /* OUT parameters */
- evtchn_port_t port;
-};
-typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t;
-
-/*
- * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
- * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify
- * a port that is unbound and marked as accepting bindings from the calling
- * domain. A fresh port is allocated in the calling domain and returned as
- * <local_port>.
- *
- * In case the peer domain has already tried to set our event channel
- * pending, before it was bound, EVTCHNOP_bind_interdomain always sets
- * the local event channel pending.
- *
- * The usual pattern of use, in the guest's upcall (or subsequent
- * handler) is as follows: (Re-enable the event channel for subsequent
- * signalling and then) check for the existence of whatever condition
- * is being waited for by other means, and take whatever action is
- * needed (if any).
- *
- * NOTES:
- * 1. <remote_dom> may be DOMID_SELF, allowing loopback connections.
- */
-struct evtchn_bind_interdomain {
- /* IN parameters. */
- domid_t remote_dom;
- evtchn_port_t remote_port;
- /* OUT parameters. */
- evtchn_port_t local_port;
-};
-typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t;
-
-/*
- * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
- * vcpu.
- * NOTES:
- * 1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list
- * in xen.h for the classification of each VIRQ.
- * 2. Global VIRQs must be allocated on VCPU0 but can subsequently be
- * re-bound via EVTCHNOP_bind_vcpu.
- * 3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu.
- * The allocated event channel is bound to the specified vcpu and the
- * binding cannot be changed.
- */
-struct evtchn_bind_virq {
- /* IN parameters. */
- uint32_t virq; /* enum virq */
- uint32_t vcpu;
- /* OUT parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_bind_virq evtchn_bind_virq_t;
-
-/*
- * EVTCHNOP_bind_pirq: Bind a local event channel to a real IRQ (PIRQ <irq>).
- * NOTES:
- * 1. A physical IRQ may be bound to at most one event channel per domain.
- * 2. Only a sufficiently-privileged domain may bind to a physical IRQ.
- */
-struct evtchn_bind_pirq {
- /* IN parameters. */
- uint32_t pirq;
-#define BIND_PIRQ__WILL_SHARE 1
- uint32_t flags; /* BIND_PIRQ__* */
- /* OUT parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_bind_pirq evtchn_bind_pirq_t;
-
-/*
- * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
- * NOTES:
- * 1. The allocated event channel is bound to the specified vcpu. The binding
- * may not be changed.
- */
-struct evtchn_bind_ipi {
- uint32_t vcpu;
- /* OUT parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_bind_ipi evtchn_bind_ipi_t;
-
-/*
- * EVTCHNOP_close: Close a local event channel <port>. If the channel is
- * interdomain then the remote end is placed in the unbound state
- * (EVTCHNSTAT_unbound), awaiting a new connection.
- */
-struct evtchn_close {
- /* IN parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_close evtchn_close_t;
-
-/*
- * EVTCHNOP_send: Send an event to the remote end of the channel whose local
- * endpoint is <port>.
- */
-struct evtchn_send {
- /* IN parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_send evtchn_send_t;
-
-/*
- * EVTCHNOP_status: Get the current status of the communication channel which
- * has an endpoint at <dom, port>.
- * NOTES:
- * 1. <dom> may be specified as DOMID_SELF.
- * 2. Only a sufficiently-privileged domain may obtain the status of an event
- * channel for which <dom> is not DOMID_SELF.
- */
-struct evtchn_status {
- /* IN parameters */
- domid_t dom;
- evtchn_port_t port;
- /* OUT parameters */
-#define EVTCHNSTAT_closed 0 /* Channel is not in use. */
-#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/
-#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */
-#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */
-#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */
-#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */
- uint32_t status;
- uint32_t vcpu; /* VCPU to which this channel is bound. */
- union {
- struct {
- domid_t dom;
- } unbound; /* EVTCHNSTAT_unbound */
- struct {
- domid_t dom;
- evtchn_port_t port;
- } interdomain; /* EVTCHNSTAT_interdomain */
- uint32_t pirq; /* EVTCHNSTAT_pirq */
- uint32_t virq; /* EVTCHNSTAT_virq */
- } u;
-};
-typedef struct evtchn_status evtchn_status_t;
-
-/*
- * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
- * event is pending.
- * NOTES:
- * 1. IPI-bound channels always notify the vcpu specified at bind time.
- * This binding cannot be changed.
- * 2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time.
- * This binding cannot be changed.
- * 3. All other channels notify vcpu0 by default. This default is set when
- * the channel is allocated (a port that is freed and subsequently reused
- * has its binding reset to vcpu0).
- */
-struct evtchn_bind_vcpu {
- /* IN parameters. */
- evtchn_port_t port;
- uint32_t vcpu;
-};
-typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t;
-
-/*
- * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
- * a notification to the appropriate VCPU if an event is pending.
- */
-struct evtchn_unmask {
- /* IN parameters. */
- evtchn_port_t port;
-};
-typedef struct evtchn_unmask evtchn_unmask_t;
-
-/*
- * EVTCHNOP_reset: Close all event channels associated with specified domain.
- * NOTES:
- * 1. <dom> may be specified as DOMID_SELF.
- * 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF.
- * 3. Destroys all control blocks and event array, resets event channel
- * operations to 2-level ABI if called with <dom> == DOMID_SELF and FIFO
- * ABI was used. Guests should not bind events during EVTCHNOP_reset call
- * as these events are likely to be lost.
- */
-struct evtchn_reset {
- /* IN parameters. */
- domid_t dom;
-};
-typedef struct evtchn_reset evtchn_reset_t;
-
-/*
- * EVTCHNOP_init_control: initialize the control block for the FIFO ABI.
- *
- * Note: any events that are currently pending will not be resent and
- * will be lost. Guests should call this before binding any event to
- * avoid losing any events.
- */
-struct evtchn_init_control {
- /* IN parameters. */
- uint64_t control_gfn;
- uint32_t offset;
- uint32_t vcpu;
- /* OUT parameters. */
- uint8_t link_bits;
- uint8_t _pad[7];
-};
-typedef struct evtchn_init_control evtchn_init_control_t;
-
-/*
- * EVTCHNOP_expand_array: add an additional page to the event array.
- */
-struct evtchn_expand_array {
- /* IN parameters. */
- uint64_t array_gfn;
-};
-typedef struct evtchn_expand_array evtchn_expand_array_t;
-
-/*
- * EVTCHNOP_set_priority: set the priority for an event channel.
- */
-struct evtchn_set_priority {
- /* IN parameters. */
- uint32_t port;
- uint32_t priority;
-};
-typedef struct evtchn_set_priority evtchn_set_priority_t;
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op)
- * `
- * Superceded by new event_channel_op() hypercall since 0x00030202.
- */
-struct evtchn_op {
- uint32_t cmd; /* enum event_channel_op */
- union {
- struct evtchn_alloc_unbound alloc_unbound;
- struct evtchn_bind_interdomain bind_interdomain;
- struct evtchn_bind_virq bind_virq;
- struct evtchn_bind_pirq bind_pirq;
- struct evtchn_bind_ipi bind_ipi;
- struct evtchn_close close;
- struct evtchn_send send;
- struct evtchn_status status;
- struct evtchn_bind_vcpu bind_vcpu;
- struct evtchn_unmask unmask;
- } u;
-};
-typedef struct evtchn_op evtchn_op_t;
-DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);
-
-/*
- * 2-level ABI
- */
-
-#define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) * 64)
-
-/*
- * FIFO ABI
- */
-
-/* Events may have priorities from 0 (highest) to 15 (lowest). */
-#define EVTCHN_FIFO_PRIORITY_MAX 0
-#define EVTCHN_FIFO_PRIORITY_DEFAULT 7
-#define EVTCHN_FIFO_PRIORITY_MIN 15
-
-#define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1)
-
-typedef uint32_t event_word_t;
-
-#define EVTCHN_FIFO_PENDING 31
-#define EVTCHN_FIFO_MASKED 30
-#define EVTCHN_FIFO_LINKED 29
-#define EVTCHN_FIFO_BUSY 28
-
-#define EVTCHN_FIFO_LINK_BITS 17
-#define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1)
-
-#define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS)
-
-struct evtchn_fifo_control_block {
- uint32_t ready;
- uint32_t _rsvd;
- uint32_t head[EVTCHN_FIFO_MAX_QUEUES];
-};
-typedef struct evtchn_fifo_control_block evtchn_fifo_control_block_t;
-
-#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * features.h
- *
- * Feature flags, reported by XENVER_get_features.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2006, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_FEATURES_H__
-#define __XEN_PUBLIC_FEATURES_H__
-
-/*
- * `incontents 200 elfnotes_features XEN_ELFNOTE_FEATURES
- *
- * The list of all the features the guest supports. They are set by
- * parsing the XEN_ELFNOTE_FEATURES and XEN_ELFNOTE_SUPPORTED_FEATURES
- * string. The format is the feature names (as given here without the
- * "XENFEAT_" prefix) separated by '|' characters.
- * If a feature is required for the kernel to function then the feature name
- * must be preceded by a '!' character.
- *
- * Note that if XEN_ELFNOTE_SUPPORTED_FEATURES is used, then in the
- * XENFEAT_dom0 MUST be set if the guest is to be booted as dom0,
- */
-
-/*
- * If set, the guest does not need to write-protect its pagetables, and can
- * update them via direct writes.
- */
-#define XENFEAT_writable_page_tables 0
-
-/*
- * If set, the guest does not need to write-protect its segment descriptor
- * tables, and can update them via direct writes.
- */
-#define XENFEAT_writable_descriptor_tables 1
-
-/*
- * If set, translation between the guest's 'pseudo-physical' address space
- * and the host's machine address space are handled by the hypervisor. In this
- * mode the guest does not need to perform phys-to/from-machine translations
- * when performing page table operations.
- */
-#define XENFEAT_auto_translated_physmap 2
-
-/* If set, the guest is running in supervisor mode (e.g., x86 ring 0). */
-#define XENFEAT_supervisor_mode_kernel 3
-
-/*
- * If set, the guest does not need to allocate x86 PAE page directories
- * below 4GB. This flag is usually implied by auto_translated_physmap.
- */
-#define XENFEAT_pae_pgdir_above_4gb 4
-
-/* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
-#define XENFEAT_mmu_pt_update_preserve_ad 5
-
-/* x86: Does this Xen host support the MMU_{CLEAR,COPY}_PAGE hypercall? */
-#define XENFEAT_highmem_assist 6
-
-/*
- * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest kernel
- * available pte bits.
- */
-#define XENFEAT_gnttab_map_avail_bits 7
-
-/* x86: Does this Xen host support the HVM callback vector type? */
-#define XENFEAT_hvm_callback_vector 8
-
-/* x86: pvclock algorithm is safe to use on HVM */
-#define XENFEAT_hvm_safe_pvclock 9
-
-/* x86: pirq can be used by HVM guests */
-#define XENFEAT_hvm_pirqs 10
-
-/* operation as Dom0 is supported */
-#define XENFEAT_dom0 11
-
-/* Xen also maps grant references at pfn = mfn.
- * This feature flag is deprecated and should not be used.
-#define XENFEAT_grant_map_identity 12
- */
-
-#define XENFEAT_NR_SUBMAPS 1
-
-#endif /* __XEN_PUBLIC_FEATURES_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * gcov.h
- *
- * Coverage structures exported by Xen.
- * Structure is different from Gcc one.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2013, Citrix Systems R&D Ltd.
- */
-
-#ifndef __XEN_PUBLIC_GCOV_H__
-#define __XEN_PUBLIC_GCOV_H__ __XEN_PUBLIC_GCOV_H__
-
-#define XENCOV_COUNTERS 5
-#define XENCOV_TAG_BASE 0x58544300u
-#define XENCOV_TAG_FILE (XENCOV_TAG_BASE+0x46u)
-#define XENCOV_TAG_FUNC (XENCOV_TAG_BASE+0x66u)
-#define XENCOV_TAG_COUNTER(n) (XENCOV_TAG_BASE+0x30u+((n)&0xfu))
-#define XENCOV_TAG_END (XENCOV_TAG_BASE+0x2eu)
-#define XENCOV_IS_TAG_COUNTER(n) \
- ((n) >= XENCOV_TAG_COUNTER(0) && (n) < XENCOV_TAG_COUNTER(XENCOV_COUNTERS))
-#define XENCOV_COUNTER_NUM(n) ((n)-XENCOV_TAG_COUNTER(0))
-
-/*
- * The main structure for the blob is
- * BLOB := FILE.. END
- * FILE := TAG_FILE VERSION STAMP FILENAME COUNTERS FUNCTIONS
- * FILENAME := LEN characters
- * characters are padded to 32 bit
- * LEN := 32 bit value
- * COUNTERS := TAG_COUNTER(n) NUM COUNTER..
- * NUM := 32 bit valie
- * COUNTER := 64 bit value
- * FUNCTIONS := TAG_FUNC NUM FUNCTION..
- * FUNCTION := IDENT CHECKSUM NUM_COUNTERS
- *
- * All tagged structures are aligned to 8 bytes
- */
-
-/**
- * File information
- * Prefixed with XENCOV_TAG_FILE and a string with filename
- * Aligned to 8 bytes
- */
-struct xencov_file
-{
- uint32_t tag; /* XENCOV_TAG_FILE */
- uint32_t version;
- uint32_t stamp;
- uint32_t fn_len;
- char filename[1];
-};
-
-
-/**
- * Counters information
- * Prefixed with XENCOV_TAG_COUNTER(n) where n is 0..(XENCOV_COUNTERS-1)
- * Aligned to 8 bytes
- */
-struct xencov_counter
-{
- uint32_t tag; /* XENCOV_TAG_COUNTER(n) */
- uint32_t num;
- uint64_t values[1];
-};
-
-/**
- * Information for each function
- * Number of counter is equal to the number of counter structures got before
- */
-struct xencov_function
-{
- uint32_t ident;
- uint32_t checksum;
- uint32_t num_counters[1];
-};
-
-/**
- * Information for all functions
- * Aligned to 8 bytes
- */
-struct xencov_functions
-{
- uint32_t tag; /* XENCOV_TAG_FUNC */
- uint32_t num;
- struct xencov_function xencov_function[1];
-};
-
-/**
- * Terminator
- */
-struct xencov_end
-{
- uint32_t tag; /* XENCOV_TAG_END */
-};
-
-#endif /* __XEN_PUBLIC_GCOV_H__ */
-
+++ /dev/null
-/******************************************************************************
- * grant_table.h
- *
- * Interface for granting foreign access to page frames, and receiving
- * page-ownership transfers.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __XEN_PUBLIC_GRANT_TABLE_H__
-#define __XEN_PUBLIC_GRANT_TABLE_H__
-
-#include "xen.h"
-
-/*
- * `incontents 150 gnttab Grant Tables
- *
- * Xen's grant tables provide a generic mechanism to memory sharing
- * between domains. This shared memory interface underpins the split
- * device drivers for block and network IO.
- *
- * Each domain has its own grant table. This is a data structure that
- * is shared with Xen; it allows the domain to tell Xen what kind of
- * permissions other domains have on its pages. Entries in the grant
- * table are identified by grant references. A grant reference is an
- * integer, which indexes into the grant table. It acts as a
- * capability which the grantee can use to perform operations on the
- * granter’s memory.
- *
- * This capability-based system allows shared-memory communications
- * between unprivileged domains. A grant reference also encapsulates
- * the details of a shared page, removing the need for a domain to
- * know the real machine address of a page it is sharing. This makes
- * it possible to share memory correctly with domains running in
- * fully virtualised memory.
- */
-
-/***********************************
- * GRANT TABLE REPRESENTATION
- */
-
-/* Some rough guidelines on accessing and updating grant-table entries
- * in a concurrency-safe manner. For more information, Linux contains a
- * reference implementation for guest OSes (drivers/xen/grant_table.c, see
- * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD
- *
- * NB. WMB is a no-op on current-generation x86 processors. However, a
- * compiler barrier will still be required.
- *
- * Introducing a valid entry into the grant table:
- * 1. Write ent->domid.
- * 2. Write ent->frame:
- * GTF_permit_access: Frame to which access is permitted.
- * GTF_accept_transfer: Pseudo-phys frame slot being filled by new
- * frame, or zero if none.
- * 3. Write memory barrier (WMB).
- * 4. Write ent->flags, inc. valid type.
- *
- * Invalidating an unused GTF_permit_access entry:
- * 1. flags = ent->flags.
- * 2. Observe that !(flags & (GTF_reading|GTF_writing)).
- * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
- * NB. No need for WMB as reuse of entry is control-dependent on success of
- * step 3, and all architectures guarantee ordering of ctrl-dep writes.
- *
- * Invalidating an in-use GTF_permit_access entry:
- * This cannot be done directly. Request assistance from the domain controller
- * which can set a timeout on the use of a grant entry and take necessary
- * action. (NB. This is not yet implemented!).
- *
- * Invalidating an unused GTF_accept_transfer entry:
- * 1. flags = ent->flags.
- * 2. Observe that !(flags & GTF_transfer_committed). [*]
- * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
- * NB. No need for WMB as reuse of entry is control-dependent on success of
- * step 3, and all architectures guarantee ordering of ctrl-dep writes.
- * [*] If GTF_transfer_committed is set then the grant entry is 'committed'.
- * The guest must /not/ modify the grant entry until the address of the
- * transferred frame is written. It is safe for the guest to spin waiting
- * for this to occur (detect by observing GTF_transfer_completed in
- * ent->flags).
- *
- * Invalidating a committed GTF_accept_transfer entry:
- * 1. Wait for (ent->flags & GTF_transfer_completed).
- *
- * Changing a GTF_permit_access from writable to read-only:
- * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.
- *
- * Changing a GTF_permit_access from read-only to writable:
- * Use SMP-safe bit-setting instruction.
- */
-
-/*
- * Reference to a grant entry in a specified domain's grant table.
- */
-typedef uint32_t grant_ref_t;
-
-/*
- * A grant table comprises a packed array of grant entries in one or more
- * page frames shared between Xen and a guest.
- * [XEN]: This field is written by Xen and read by the sharing guest.
- * [GST]: This field is written by the guest and read by Xen.
- */
-
-/*
- * Version 1 of the grant table entry structure is maintained purely
- * for backwards compatibility. New guests should use version 2.
- */
-#if __XEN_INTERFACE_VERSION__ < 0x0003020a
-#define grant_entry_v1 grant_entry
-#define grant_entry_v1_t grant_entry_t
-#endif
-struct grant_entry_v1 {
- /* GTF_xxx: various type and flag information. [XEN,GST] */
- uint16_t flags;
- /* The domain being granted foreign privileges. [GST] */
- domid_t domid;
- /*
- * GTF_permit_access: Frame that @domid is allowed to map and access. [GST]
- * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]
- */
- uint32_t frame;
-};
-typedef struct grant_entry_v1 grant_entry_v1_t;
-
-/* The first few grant table entries will be preserved across grant table
- * version changes and may be pre-populated at domain creation by tools.
- */
-#define GNTTAB_NR_RESERVED_ENTRIES 8
-#define GNTTAB_RESERVED_CONSOLE 0
-#define GNTTAB_RESERVED_XENSTORE 1
-
-/*
- * Type of grant entry.
- * GTF_invalid: This grant entry grants no privileges.
- * GTF_permit_access: Allow @domid to map/access @frame.
- * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
- * to this guest. Xen writes the page number to @frame.
- * GTF_transitive: Allow @domid to transitively access a subrange of
- * @trans_grant in @trans_domid. No mappings are allowed.
- */
-#define GTF_invalid (0U<<0)
-#define GTF_permit_access (1U<<0)
-#define GTF_accept_transfer (2U<<0)
-#define GTF_transitive (3U<<0)
-#define GTF_type_mask (3U<<0)
-
-/*
- * Subflags for GTF_permit_access.
- * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
- * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
- * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
- * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
- * GTF_sub_page: Grant access to only a subrange of the page. @domid
- * will only be allowed to copy from the grant, and not
- * map it. [GST]
- */
-#define _GTF_readonly (2)
-#define GTF_readonly (1U<<_GTF_readonly)
-#define _GTF_reading (3)
-#define GTF_reading (1U<<_GTF_reading)
-#define _GTF_writing (4)
-#define GTF_writing (1U<<_GTF_writing)
-#define _GTF_PWT (5)
-#define GTF_PWT (1U<<_GTF_PWT)
-#define _GTF_PCD (6)
-#define GTF_PCD (1U<<_GTF_PCD)
-#define _GTF_PAT (7)
-#define GTF_PAT (1U<<_GTF_PAT)
-#define _GTF_sub_page (8)
-#define GTF_sub_page (1U<<_GTF_sub_page)
-
-/*
- * Subflags for GTF_accept_transfer:
- * GTF_transfer_committed: Xen sets this flag to indicate that it is committed
- * to transferring ownership of a page frame. When a guest sees this flag
- * it must /not/ modify the grant entry until GTF_transfer_completed is
- * set by Xen.
- * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag
- * after reading GTF_transfer_committed. Xen will always write the frame
- * address, followed by ORing this flag, in a timely manner.
- */
-#define _GTF_transfer_committed (2)
-#define GTF_transfer_committed (1U<<_GTF_transfer_committed)
-#define _GTF_transfer_completed (3)
-#define GTF_transfer_completed (1U<<_GTF_transfer_completed)
-
-/*
- * Version 2 grant table entries. These fulfil the same role as
- * version 1 entries, but can represent more complicated operations.
- * Any given domain will have either a version 1 or a version 2 table,
- * and every entry in the table will be the same version.
- *
- * The interface by which domains use grant references does not depend
- * on the grant table version in use by the other domain.
- */
-#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
-/*
- * Version 1 and version 2 grant entries share a common prefix. The
- * fields of the prefix are documented as part of struct
- * grant_entry_v1.
- */
-struct grant_entry_header {
- uint16_t flags;
- domid_t domid;
-};
-typedef struct grant_entry_header grant_entry_header_t;
-
-/*
- * Version 2 of the grant entry structure.
- */
-union grant_entry_v2 {
- grant_entry_header_t hdr;
-
- /*
- * This member is used for V1-style full page grants, where either:
- *
- * -- hdr.type is GTF_accept_transfer, or
- * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.
- *
- * In that case, the frame field has the same semantics as the
- * field of the same name in the V1 entry structure.
- */
- struct {
- grant_entry_header_t hdr;
- uint32_t pad0;
- uint64_t frame;
- } full_page;
-
- /*
- * If the grant type is GTF_grant_access and GTF_sub_page is set,
- * @domid is allowed to access bytes [@page_off,@page_off+@length)
- * in frame @frame.
- */
- struct {
- grant_entry_header_t hdr;
- uint16_t page_off;
- uint16_t length;
- uint64_t frame;
- } sub_page;
-
- /*
- * If the grant is GTF_transitive, @domid is allowed to use the
- * grant @gref in domain @trans_domid, as if it was the local
- * domain. Obviously, the transitive access must be compatible
- * with the original grant.
- *
- * The current version of Xen does not allow transitive grants
- * to be mapped.
- */
- struct {
- grant_entry_header_t hdr;
- domid_t trans_domid;
- uint16_t pad0;
- grant_ref_t gref;
- } transitive;
-
- uint32_t __spacer[4]; /* Pad to a power of two */
-};
-typedef union grant_entry_v2 grant_entry_v2_t;
-
-typedef uint16_t grant_status_t;
-
-#endif /* __XEN_INTERFACE_VERSION__ */
-
-/***********************************
- * GRANT TABLE QUERIES AND USES
- */
-
-/* ` enum neg_errnoval
- * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd,
- * ` void *args,
- * ` unsigned int count)
- * `
- *
- * @args points to an array of a per-command data structure. The array
- * has @count members
- */
-
-/* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */
-#define GNTTABOP_map_grant_ref 0
-#define GNTTABOP_unmap_grant_ref 1
-#define GNTTABOP_setup_table 2
-#define GNTTABOP_dump_table 3
-#define GNTTABOP_transfer 4
-#define GNTTABOP_copy 5
-#define GNTTABOP_query_size 6
-#define GNTTABOP_unmap_and_replace 7
-#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
-#define GNTTABOP_set_version 8
-#define GNTTABOP_get_status_frames 9
-#define GNTTABOP_get_version 10
-#define GNTTABOP_swap_grant_ref 11
-#define GNTTABOP_cache_flush 12
-#endif /* __XEN_INTERFACE_VERSION__ */
-/* ` } */
-
-/*
- * Handle to track a mapping created via a grant reference.
- */
-typedef uint32_t grant_handle_t;
-
-/*
- * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access
- * by devices and/or host CPUs. If successful, <handle> is a tracking number
- * that must be presented later to destroy the mapping(s). On error, <handle>
- * is a negative status code.
- * NOTES:
- * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address
- * via which I/O devices may access the granted frame.
- * 2. If GNTMAP_host_map is specified then a mapping will be added at
- * either a host virtual address in the current address space, or at
- * a PTE at the specified machine address. The type of mapping to
- * perform is selected through the GNTMAP_contains_pte flag, and the
- * address is specified in <host_addr>.
- * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a
- * host mapping is destroyed by other means then it is *NOT* guaranteed
- * to be accounted to the correct grant reference!
- */
-struct gnttab_map_grant_ref {
- /* IN parameters. */
- uint64_t host_addr;
- uint32_t flags; /* GNTMAP_* */
- grant_ref_t ref;
- domid_t dom;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
- grant_handle_t handle;
- uint64_t dev_bus_addr;
-};
-typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);
-
-/*
- * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
- * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that
- * field is ignored. If non-zero, they must refer to a device/host mapping
- * that is tracked by <handle>
- * NOTES:
- * 1. The call may fail in an undefined manner if either mapping is not
- * tracked by <handle>.
- * 3. After executing a batch of unmaps, it is guaranteed that no stale
- * mappings will remain in the device or host TLBs.
- */
-struct gnttab_unmap_grant_ref {
- /* IN parameters. */
- uint64_t host_addr;
- uint64_t dev_bus_addr;
- grant_handle_t handle;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
-};
-typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
-
-/*
- * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least
- * <nr_frames> pages. The frame addresses are written to the <frame_list>.
- * Only <nr_frames> addresses are written, even if the table is larger.
- * NOTES:
- * 1. <dom> may be specified as DOMID_SELF.
- * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
- * 3. Xen may not support more than a single grant-table page per domain.
- */
-struct gnttab_setup_table {
- /* IN parameters. */
- domid_t dom;
- uint32_t nr_frames;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
-#if __XEN_INTERFACE_VERSION__ < 0x00040300
- XEN_GUEST_HANDLE(ulong) frame_list;
-#else
- XEN_GUEST_HANDLE(xen_pfn_t) frame_list;
-#endif
-};
-typedef struct gnttab_setup_table gnttab_setup_table_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t);
-
-/*
- * GNTTABOP_dump_table: Dump the contents of the grant table to the
- * xen console. Debugging use only.
- */
-struct gnttab_dump_table {
- /* IN parameters. */
- domid_t dom;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
-};
-typedef struct gnttab_dump_table gnttab_dump_table_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);
-
-/*
- * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
- * foreign domain has previously registered its interest in the transfer via
- * <domid, ref>.
- *
- * Note that, even if the transfer fails, the specified page no longer belongs
- * to the calling domain *unless* the error is GNTST_bad_page.
- */
-struct gnttab_transfer {
- /* IN parameters. */
- xen_pfn_t mfn;
- domid_t domid;
- grant_ref_t ref;
- /* OUT parameters. */
- int16_t status;
-};
-typedef struct gnttab_transfer gnttab_transfer_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);
-
-
-/*
- * GNTTABOP_copy: Hypervisor based copy
- * source and destinations can be eithers MFNs or, for foreign domains,
- * grant references. the foreign domain has to grant read/write access
- * in its grant table.
- *
- * The flags specify what type source and destinations are (either MFN
- * or grant reference).
- *
- * Note that this can also be used to copy data between two domains
- * via a third party if the source and destination domains had previously
- * grant appropriate access to their pages to the third party.
- *
- * source_offset specifies an offset in the source frame, dest_offset
- * the offset in the target frame and len specifies the number of
- * bytes to be copied.
- */
-
-#define _GNTCOPY_source_gref (0)
-#define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref)
-#define _GNTCOPY_dest_gref (1)
-#define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref)
-
-struct gnttab_copy {
- /* IN parameters. */
- struct {
- union {
- grant_ref_t ref;
- xen_pfn_t gmfn;
- } u;
- domid_t domid;
- uint16_t offset;
- } source, dest;
- uint16_t len;
- uint16_t flags; /* GNTCOPY_* */
- /* OUT parameters. */
- int16_t status;
-};
-typedef struct gnttab_copy gnttab_copy_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t);
-
-/*
- * GNTTABOP_query_size: Query the current and maximum sizes of the shared
- * grant table.
- * NOTES:
- * 1. <dom> may be specified as DOMID_SELF.
- * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
- */
-struct gnttab_query_size {
- /* IN parameters. */
- domid_t dom;
- /* OUT parameters. */
- uint32_t nr_frames;
- uint32_t max_nr_frames;
- int16_t status; /* => enum grant_status */
-};
-typedef struct gnttab_query_size gnttab_query_size_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t);
-
-/*
- * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings
- * tracked by <handle> but atomically replace the page table entry with one
- * pointing to the machine address under <new_addr>. <new_addr> will be
- * redirected to the null entry.
- * NOTES:
- * 1. The call may fail in an undefined manner if either mapping is not
- * tracked by <handle>.
- * 2. After executing a batch of unmaps, it is guaranteed that no stale
- * mappings will remain in the device or host TLBs.
- */
-struct gnttab_unmap_and_replace {
- /* IN parameters. */
- uint64_t host_addr;
- uint64_t new_addr;
- grant_handle_t handle;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
-};
-typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t);
-
-#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
-/*
- * GNTTABOP_set_version: Request a particular version of the grant
- * table shared table structure. This operation can only be performed
- * once in any given domain. It must be performed before any grants
- * are activated; otherwise, the domain will be stuck with version 1.
- * The only defined versions are 1 and 2.
- */
-struct gnttab_set_version {
- /* IN/OUT parameters */
- uint32_t version;
-};
-typedef struct gnttab_set_version gnttab_set_version_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_set_version_t);
-
-
-/*
- * GNTTABOP_get_status_frames: Get the list of frames used to store grant
- * status for <dom>. In grant format version 2, the status is separated
- * from the other shared grant fields to allow more efficient synchronization
- * using barriers instead of atomic cmpexch operations.
- * <nr_frames> specify the size of vector <frame_list>.
- * The frame addresses are returned in the <frame_list>.
- * Only <nr_frames> addresses are returned, even if the table is larger.
- * NOTES:
- * 1. <dom> may be specified as DOMID_SELF.
- * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
- */
-struct gnttab_get_status_frames {
- /* IN parameters. */
- uint32_t nr_frames;
- domid_t dom;
- /* OUT parameters. */
- int16_t status; /* => enum grant_status */
- XEN_GUEST_HANDLE(uint64_t) frame_list;
-};
-typedef struct gnttab_get_status_frames gnttab_get_status_frames_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_t);
-
-/*
- * GNTTABOP_get_version: Get the grant table version which is in
- * effect for domain <dom>.
- */
-struct gnttab_get_version {
- /* IN parameters */
- domid_t dom;
- uint16_t pad;
- /* OUT parameters */
- uint32_t version;
-};
-typedef struct gnttab_get_version gnttab_get_version_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t);
-
-/*
- * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries.
- */
-struct gnttab_swap_grant_ref {
- /* IN parameters */
- grant_ref_t ref_a;
- grant_ref_t ref_b;
- /* OUT parameters */
- int16_t status; /* => enum grant_status */
-};
-typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t);
-
-/*
- * Issue one or more cache maintenance operations on a portion of a
- * page granted to the calling domain by a foreign domain.
- */
-struct gnttab_cache_flush {
- union {
- uint64_t dev_bus_addr;
- grant_ref_t ref;
- } a;
- uint16_t offset; /* offset from start of grant */
- uint16_t length; /* size within the grant */
-#define GNTTAB_CACHE_CLEAN (1<<0)
-#define GNTTAB_CACHE_INVAL (1<<1)
-#define GNTTAB_CACHE_SOURCE_GREF (1<<31)
- uint32_t op;
-};
-typedef struct gnttab_cache_flush gnttab_cache_flush_t;
-DEFINE_XEN_GUEST_HANDLE(gnttab_cache_flush_t);
-
-#endif /* __XEN_INTERFACE_VERSION__ */
-
-/*
- * Bitfield values for gnttab_map_grant_ref.flags.
- */
- /* Map the grant entry for access by I/O devices. */
-#define _GNTMAP_device_map (0)
-#define GNTMAP_device_map (1<<_GNTMAP_device_map)
- /* Map the grant entry for access by host CPUs. */
-#define _GNTMAP_host_map (1)
-#define GNTMAP_host_map (1<<_GNTMAP_host_map)
- /* Accesses to the granted frame will be restricted to read-only access. */
-#define _GNTMAP_readonly (2)
-#define GNTMAP_readonly (1<<_GNTMAP_readonly)
- /*
- * GNTMAP_host_map subflag:
- * 0 => The host mapping is usable only by the guest OS.
- * 1 => The host mapping is usable by guest OS + current application.
- */
-#define _GNTMAP_application_map (3)
-#define GNTMAP_application_map (1<<_GNTMAP_application_map)
-
- /*
- * GNTMAP_contains_pte subflag:
- * 0 => This map request contains a host virtual address.
- * 1 => This map request contains the machine addess of the PTE to update.
- */
-#define _GNTMAP_contains_pte (4)
-#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
-
-#define _GNTMAP_can_fail (5)
-#define GNTMAP_can_fail (1<<_GNTMAP_can_fail)
-
-/*
- * Bits to be placed in guest kernel available PTE bits (architecture
- * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
- */
-#define _GNTMAP_guest_avail0 (16)
-#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0)
-
-/*
- * Values for error status returns. All errors are -ve.
- */
-/* ` enum grant_status { */
-#define GNTST_okay (0) /* Normal return. */
-#define GNTST_general_error (-1) /* General undefined error. */
-#define GNTST_bad_domain (-2) /* Unrecognsed domain id. */
-#define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */
-#define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */
-#define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */
-#define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/
-#define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */
-#define GNTST_permission_denied (-8) /* Not enough privilege for operation. */
-#define GNTST_bad_page (-9) /* Specified page was invalid for op. */
-#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */
-#define GNTST_address_too_big (-11) /* transfer page address too large. */
-#define GNTST_eagain (-12) /* Operation not done; try again. */
-/* ` } */
-
-#define GNTTABOP_error_msgs { \
- "okay", \
- "undefined error", \
- "unrecognised domain id", \
- "invalid grant reference", \
- "invalid mapping handle", \
- "invalid virtual address", \
- "invalid device address", \
- "no spare translation slot in the I/O MMU", \
- "permission denied", \
- "bad page", \
- "copy arguments cross page boundary", \
- "page address size too large", \
- "operation not done; try again" \
-}
-
-#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_E820_H__
-#define __XEN_PUBLIC_HVM_E820_H__
-
-/* E820 location in HVM virtual address space. */
-#define HVM_E820_PAGE 0x00090000
-#define HVM_E820_NR_OFFSET 0x000001E8
-#define HVM_E820_OFFSET 0x000002D0
-
-#define HVM_BELOW_4G_RAM_END 0xF0000000
-#define HVM_BELOW_4G_MMIO_START HVM_BELOW_4G_RAM_END
-#define HVM_BELOW_4G_MMIO_LENGTH ((1ULL << 32) - HVM_BELOW_4G_MMIO_START)
-
-#endif /* __XEN_PUBLIC_HVM_E820_H__ */
+++ /dev/null
-/******************************************************************************
- * hvm/hvm_info_table.h
- *
- * HVM parameter and information table, written into guest memory map.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
-#define __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
-
-#define HVM_INFO_PFN 0x09F
-#define HVM_INFO_OFFSET 0x800
-#define HVM_INFO_PADDR ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
-
-/* Maximum we can support with current vLAPIC ID mapping. */
-#define HVM_MAX_VCPUS 128
-
-struct hvm_info_table {
- char signature[8]; /* "HVM INFO" */
- uint32_t length;
- uint8_t checksum;
-
- /* Should firmware build APIC descriptors (APIC MADT / MP BIOS)? */
- uint8_t apic_mode;
-
- /* How many CPUs does this domain have? */
- uint32_t nr_vcpus;
-
- /*
- * MEMORY MAP provided by HVM domain builder.
- * Notes:
- * 1. page_to_phys(x) = x << 12
- * 2. If a field is zero, the corresponding range does not exist.
- */
- /*
- * 0x0 to page_to_phys(low_mem_pgend)-1:
- * RAM below 4GB (except for VGA hole 0xA0000-0xBFFFF)
- */
- uint32_t low_mem_pgend;
- /*
- * page_to_phys(reserved_mem_pgstart) to 0xFFFFFFFF:
- * Reserved for special memory mappings
- */
- uint32_t reserved_mem_pgstart;
- /*
- * 0x100000000 to page_to_phys(high_mem_pgend)-1:
- * RAM above 4GB
- */
- uint32_t high_mem_pgend;
-
- /* Bitmap of which CPUs are online at boot time. */
- uint8_t vcpu_online[(HVM_MAX_VCPUS + 7)/8];
-};
-
-#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
-#define __XEN_PUBLIC_HVM_HVM_OP_H__
-
-#include "../xen.h"
-#include "../trace.h"
-#include "../event_channel.h"
-
-/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
-#define HVMOP_set_param 0
-#define HVMOP_get_param 1
-struct xen_hvm_param {
- domid_t domid; /* IN */
- uint32_t index; /* IN */
- uint64_t value; /* IN/OUT */
-};
-typedef struct xen_hvm_param xen_hvm_param_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
-
-/* Set the logical level of one of a domain's PCI INTx wires. */
-#define HVMOP_set_pci_intx_level 2
-struct xen_hvm_set_pci_intx_level {
- /* Domain to be updated. */
- domid_t domid;
- /* PCI INTx identification in PCI topology (domain:bus:device:intx). */
- uint8_t domain, bus, device, intx;
- /* Assertion level (0 = unasserted, 1 = asserted). */
- uint8_t level;
-};
-typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t);
-
-/* Set the logical level of one of a domain's ISA IRQ wires. */
-#define HVMOP_set_isa_irq_level 3
-struct xen_hvm_set_isa_irq_level {
- /* Domain to be updated. */
- domid_t domid;
- /* ISA device identification, by ISA IRQ (0-15). */
- uint8_t isa_irq;
- /* Assertion level (0 = unasserted, 1 = asserted). */
- uint8_t level;
-};
-typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t);
-
-#define HVMOP_set_pci_link_route 4
-struct xen_hvm_set_pci_link_route {
- /* Domain to be updated. */
- domid_t domid;
- /* PCI link identifier (0-3). */
- uint8_t link;
- /* ISA IRQ (1-15), or 0 (disable link). */
- uint8_t isa_irq;
-};
-typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t);
-
-/* Flushes all VCPU TLBs: @arg must be NULL. */
-#define HVMOP_flush_tlbs 5
-
-typedef enum {
- HVMMEM_ram_rw, /* Normal read/write guest RAM */
- HVMMEM_ram_ro, /* Read-only; writes are discarded */
- HVMMEM_mmio_dm, /* Reads and write go to the device model */
- HVMMEM_mmio_write_dm /* Read-only; writes go to the device model */
-} hvmmem_type_t;
-
-/* Following tools-only interfaces may change in future. */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-/* Track dirty VRAM. */
-#define HVMOP_track_dirty_vram 6
-struct xen_hvm_track_dirty_vram {
- /* Domain to be tracked. */
- domid_t domid;
- /* Number of pages to track. */
- uint32_t nr;
- /* First pfn to track. */
- uint64_aligned_t first_pfn;
- /* OUT variable. */
- /* Dirty bitmap buffer. */
- XEN_GUEST_HANDLE_64(uint8) dirty_bitmap;
-};
-typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t);
-
-/* Notify that some pages got modified by the Device Model. */
-#define HVMOP_modified_memory 7
-struct xen_hvm_modified_memory {
- /* Domain to be updated. */
- domid_t domid;
- /* Number of pages. */
- uint32_t nr;
- /* First pfn. */
- uint64_aligned_t first_pfn;
-};
-typedef struct xen_hvm_modified_memory xen_hvm_modified_memory_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_modified_memory_t);
-
-#define HVMOP_set_mem_type 8
-/* Notify that a region of memory is to be treated in a specific way. */
-struct xen_hvm_set_mem_type {
- /* Domain to be updated. */
- domid_t domid;
- /* Memory type */
- uint16_t hvmmem_type;
- /* Number of pages. */
- uint32_t nr;
- /* First pfn. */
- uint64_aligned_t first_pfn;
-};
-typedef struct xen_hvm_set_mem_type xen_hvm_set_mem_type_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_type_t);
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
-/* Hint from PV drivers for pagetable destruction. */
-#define HVMOP_pagetable_dying 9
-struct xen_hvm_pagetable_dying {
- /* Domain with a pagetable about to be destroyed. */
- domid_t domid;
- uint16_t pad[3]; /* align next field on 8-byte boundary */
- /* guest physical address of the toplevel pagetable dying */
- uint64_t gpa;
-};
-typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_pagetable_dying_t);
-
-/* Get the current Xen time, in nanoseconds since system boot. */
-#define HVMOP_get_time 10
-struct xen_hvm_get_time {
- uint64_t now; /* OUT */
-};
-typedef struct xen_hvm_get_time xen_hvm_get_time_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_time_t);
-
-#define HVMOP_xentrace 11
-struct xen_hvm_xentrace {
- uint16_t event, extra_bytes;
- uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)];
-};
-typedef struct xen_hvm_xentrace xen_hvm_xentrace_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t);
-
-/* Following tools-only interfaces may change in future. */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-/* Deprecated by XENMEM_access_op_set_access */
-#define HVMOP_set_mem_access 12
-
-/* Deprecated by XENMEM_access_op_get_access */
-#define HVMOP_get_mem_access 13
-
-#define HVMOP_inject_trap 14
-/* Inject a trap into a VCPU, which will get taken up on the next
- * scheduling of it. Note that the caller should know enough of the
- * state of the CPU before injecting, to know what the effect of
- * injecting the trap will be.
- */
-struct xen_hvm_inject_trap {
- /* Domain to be queried. */
- domid_t domid;
- /* VCPU */
- uint32_t vcpuid;
- /* Vector number */
- uint32_t vector;
- /* Trap type (HVMOP_TRAP_*) */
- uint32_t type;
-/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */
-# define HVMOP_TRAP_ext_int 0 /* external interrupt */
-# define HVMOP_TRAP_nmi 2 /* nmi */
-# define HVMOP_TRAP_hw_exc 3 /* hardware exception */
-# define HVMOP_TRAP_sw_int 4 /* software interrupt (CD nn) */
-# define HVMOP_TRAP_pri_sw_exc 5 /* ICEBP (F1) */
-# define HVMOP_TRAP_sw_exc 6 /* INT3 (CC), INTO (CE) */
- /* Error code, or ~0u to skip */
- uint32_t error_code;
- /* Intruction length */
- uint32_t insn_len;
- /* CR2 for page faults */
- uint64_aligned_t cr2;
-};
-typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t);
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
-#define HVMOP_get_mem_type 15
-/* Return hvmmem_type_t for the specified pfn. */
-struct xen_hvm_get_mem_type {
- /* Domain to be queried. */
- domid_t domid;
- /* OUT variable. */
- uint16_t mem_type;
- uint16_t pad[2]; /* align next field on 8-byte boundary */
- /* IN variable. */
- uint64_t pfn;
-};
-typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t);
-
-/* Following tools-only interfaces may change in future. */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-/* MSI injection for emulated devices */
-#define HVMOP_inject_msi 16
-struct xen_hvm_inject_msi {
- /* Domain to be injected */
- domid_t domid;
- /* Data -- lower 32 bits */
- uint32_t data;
- /* Address (0xfeexxxxx) */
- uint64_t addr;
-};
-typedef struct xen_hvm_inject_msi xen_hvm_inject_msi_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_msi_t);
-
-/*
- * IOREQ Servers
- *
- * The interface between an I/O emulator an Xen is called an IOREQ Server.
- * A domain supports a single 'legacy' IOREQ Server which is instantiated if
- * parameter...
- *
- * HVM_PARAM_IOREQ_PFN is read (to get the gmfn containing the synchronous
- * ioreq structures), or...
- * HVM_PARAM_BUFIOREQ_PFN is read (to get the gmfn containing the buffered
- * ioreq ring), or...
- * HVM_PARAM_BUFIOREQ_EVTCHN is read (to get the event channel that Xen uses
- * to request buffered I/O emulation).
- *
- * The following hypercalls facilitate the creation of IOREQ Servers for
- * 'secondary' emulators which are invoked to implement port I/O, memory, or
- * PCI config space ranges which they explicitly register.
- */
-
-typedef uint16_t ioservid_t;
-
-/*
- * HVMOP_create_ioreq_server: Instantiate a new IOREQ Server for a secondary
- * emulator servicing domain <domid>.
- *
- * The <id> handed back is unique for <domid>. If <handle_bufioreq> is zero
- * the buffered ioreq ring will not be allocated and hence all emulation
- * requestes to this server will be synchronous.
- */
-#define HVMOP_create_ioreq_server 17
-struct xen_hvm_create_ioreq_server {
- domid_t domid; /* IN - domain to be serviced */
- uint8_t handle_bufioreq; /* IN - should server handle buffered ioreqs */
- ioservid_t id; /* OUT - server id */
-};
-typedef struct xen_hvm_create_ioreq_server xen_hvm_create_ioreq_server_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_create_ioreq_server_t);
-
-/*
- * HVMOP_get_ioreq_server_info: Get all the information necessary to access
- * IOREQ Server <id>.
- *
- * The emulator needs to map the synchronous ioreq structures and buffered
- * ioreq ring (if it exists) that Xen uses to request emulation. These are
- * hosted in domain <domid>'s gmfns <ioreq_pfn> and <bufioreq_pfn>
- * respectively. In addition, if the IOREQ Server is handling buffered
- * emulation requests, the emulator needs to bind to event channel
- * <bufioreq_port> to listen for them. (The event channels used for
- * synchronous emulation requests are specified in the per-CPU ioreq
- * structures in <ioreq_pfn>).
- * If the IOREQ Server is not handling buffered emulation requests then the
- * values handed back in <bufioreq_pfn> and <bufioreq_port> will both be 0.
- */
-#define HVMOP_get_ioreq_server_info 18
-struct xen_hvm_get_ioreq_server_info {
- domid_t domid; /* IN - domain to be serviced */
- ioservid_t id; /* IN - server id */
- evtchn_port_t bufioreq_port; /* OUT - buffered ioreq port */
- uint64_aligned_t ioreq_pfn; /* OUT - sync ioreq pfn */
- uint64_aligned_t bufioreq_pfn; /* OUT - buffered ioreq pfn */
-};
-typedef struct xen_hvm_get_ioreq_server_info xen_hvm_get_ioreq_server_info_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
-
-/*
- * HVM_map_io_range_to_ioreq_server: Register an I/O range of domain <domid>
- * for emulation by the client of IOREQ
- * Server <id>
- * HVM_unmap_io_range_from_ioreq_server: Deregister an I/O range of <domid>
- * for emulation by the client of IOREQ
- * Server <id>
- *
- * There are three types of I/O that can be emulated: port I/O, memory accesses
- * and PCI config space accesses. The <type> field denotes which type of range
- * the <start> and <end> (inclusive) fields are specifying.
- * PCI config space ranges are specified by segment/bus/device/function values
- * which should be encoded using the HVMOP_PCI_SBDF helper macro below.
- *
- * NOTE: unless an emulation request falls entirely within a range mapped
- * by a secondary emulator, it will not be passed to that emulator.
- */
-#define HVMOP_map_io_range_to_ioreq_server 19
-#define HVMOP_unmap_io_range_from_ioreq_server 20
-struct xen_hvm_io_range {
- domid_t domid; /* IN - domain to be serviced */
- ioservid_t id; /* IN - server id */
- uint32_t type; /* IN - type of range */
-# define HVMOP_IO_RANGE_PORT 0 /* I/O port range */
-# define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
-# define HVMOP_IO_RANGE_PCI 2 /* PCI segment/bus/dev/func range */
- uint64_aligned_t start, end; /* IN - inclusive start and end of range */
-};
-typedef struct xen_hvm_io_range xen_hvm_io_range_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_io_range_t);
-
-#define HVMOP_PCI_SBDF(s,b,d,f) \
- ((((s) & 0xffff) << 16) | \
- (((b) & 0xff) << 8) | \
- (((d) & 0x1f) << 3) | \
- ((f) & 0x07))
-
-/*
- * HVMOP_destroy_ioreq_server: Destroy the IOREQ Server <id> servicing domain
- * <domid>.
- *
- * Any registered I/O ranges will be automatically deregistered.
- */
-#define HVMOP_destroy_ioreq_server 21
-struct xen_hvm_destroy_ioreq_server {
- domid_t domid; /* IN - domain to be serviced */
- ioservid_t id; /* IN - server id */
-};
-typedef struct xen_hvm_destroy_ioreq_server xen_hvm_destroy_ioreq_server_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_destroy_ioreq_server_t);
-
-/*
- * HVMOP_set_ioreq_server_state: Enable or disable the IOREQ Server <id> servicing
- * domain <domid>.
- *
- * The IOREQ Server will not be passed any emulation requests until it is in the
- * enabled state.
- * Note that the contents of the ioreq_pfn and bufioreq_fn (see
- * HVMOP_get_ioreq_server_info) are not meaningful until the IOREQ Server is in
- * the enabled state.
- */
-#define HVMOP_set_ioreq_server_state 22
-struct xen_hvm_set_ioreq_server_state {
- domid_t domid; /* IN - domain to be serviced */
- ioservid_t id; /* IN - server id */
- uint8_t enabled; /* IN - enabled? */
-};
-typedef struct xen_hvm_set_ioreq_server_state xen_hvm_set_ioreq_server_state_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_ioreq_server_state_t);
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
-#if defined(__i386__) || defined(__x86_64__)
-
-/*
- * HVMOP_set_evtchn_upcall_vector: Set a <vector> that should be used for event
- * channel upcalls on the specified <vcpu>. If set,
- * this vector will be used in preference to the
- * domain global callback via (see
- * HVM_PARAM_CALLBACK_IRQ).
- */
-#define HVMOP_set_evtchn_upcall_vector 23
-struct xen_hvm_evtchn_upcall_vector {
- uint32_t vcpu;
- uint8_t vector;
-};
-typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t);
-
-#endif /* defined(__i386__) || defined(__x86_64__) */
-
-#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * hvm/hvm_xs_strings.h
- *
- * HVM xenstore strings used in HVMLOADER.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__
-#define __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__
-
-#define HVM_XS_HVMLOADER "hvmloader"
-#define HVM_XS_BIOS "hvmloader/bios"
-#define HVM_XS_GENERATION_ID_ADDRESS "hvmloader/generation-id-address"
-#define HVM_XS_ALLOW_MEMORY_RELOCATE "hvmloader/allow-memory-relocate"
-
-/* The following values allow additional ACPI tables to be added to the
- * virtual ACPI BIOS that hvmloader constructs. The values specify the guest
- * physical address and length of a block of ACPI tables to add. The format of
- * the block is simply concatenated raw tables (which specify their own length
- * in the ACPI header).
- */
-#define HVM_XS_ACPI_PT_ADDRESS "hvmloader/acpi/address"
-#define HVM_XS_ACPI_PT_LENGTH "hvmloader/acpi/length"
-
-/* Any number of SMBIOS types can be passed through to an HVM guest using
- * the following xenstore values. The values specify the guest physical
- * address and length of a block of SMBIOS structures for hvmloader to use.
- * The block is formatted in the following way:
- *
- * <length><struct><length><struct>...
- *
- * Each length separator is a 32b integer indicating the length of the next
- * SMBIOS structure. For DMTF defined types (0 - 121), the passed in struct
- * will replace the default structure in hvmloader. In addition, any
- * OEM/vendortypes (128 - 255) will all be added.
- */
-#define HVM_XS_SMBIOS_PT_ADDRESS "hvmloader/smbios/address"
-#define HVM_XS_SMBIOS_PT_LENGTH "hvmloader/smbios/length"
-
-/* Set to 1 to enable SMBIOS default portable battery (type 22) values. */
-#define HVM_XS_SMBIOS_DEFAULT_BATTERY "hvmloader/smbios/default_battery"
-
-/* The following xenstore values are used to override some of the default
- * string values in the SMBIOS table constructed in hvmloader.
- */
-#define HVM_XS_BIOS_STRINGS "bios-strings"
-#define HVM_XS_BIOS_VENDOR "bios-strings/bios-vendor"
-#define HVM_XS_BIOS_VERSION "bios-strings/bios-version"
-#define HVM_XS_SYSTEM_MANUFACTURER "bios-strings/system-manufacturer"
-#define HVM_XS_SYSTEM_PRODUCT_NAME "bios-strings/system-product-name"
-#define HVM_XS_SYSTEM_VERSION "bios-strings/system-version"
-#define HVM_XS_SYSTEM_SERIAL_NUMBER "bios-strings/system-serial-number"
-#define HVM_XS_ENCLOSURE_MANUFACTURER "bios-strings/enclosure-manufacturer"
-#define HVM_XS_ENCLOSURE_SERIAL_NUMBER "bios-strings/enclosure-serial-number"
-#define HVM_XS_BATTERY_MANUFACTURER "bios-strings/battery-manufacturer"
-#define HVM_XS_BATTERY_DEVICE_NAME "bios-strings/battery-device-name"
-
-/* 1 to 99 OEM strings can be set in xenstore using values of the form
- * below. These strings will be loaded into the SMBIOS type 11 structure.
- */
-#define HVM_XS_OEM_STRINGS "bios-strings/oem-%d"
-
-#endif /* __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ */
+++ /dev/null
-/*
- * ioreq.h: I/O request definitions for device models
- * Copyright (c) 2004, Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _IOREQ_H_
-#define _IOREQ_H_
-
-#define IOREQ_READ 1
-#define IOREQ_WRITE 0
-
-#define STATE_IOREQ_NONE 0
-#define STATE_IOREQ_READY 1
-#define STATE_IOREQ_INPROCESS 2
-#define STATE_IORESP_READY 3
-
-#define IOREQ_TYPE_PIO 0 /* pio */
-#define IOREQ_TYPE_COPY 1 /* mmio ops */
-#define IOREQ_TYPE_PCI_CONFIG 2
-#define IOREQ_TYPE_TIMEOFFSET 7
-#define IOREQ_TYPE_INVALIDATE 8 /* mapcache */
-
-/*
- * VMExit dispatcher should cooperate with instruction decoder to
- * prepare this structure and notify service OS and DM by sending
- * virq.
- *
- * For I/O type IOREQ_TYPE_PCI_CONFIG, the physical address is formatted
- * as follows:
- *
- * 63....48|47..40|39..35|34..32|31........0
- * SEGMENT |BUS |DEV |FN |OFFSET
- */
-struct ioreq {
- uint64_t addr; /* physical address */
- uint64_t data; /* data (or paddr of data) */
- uint32_t count; /* for rep prefixes */
- uint32_t size; /* size in bytes */
- uint32_t vp_eport; /* evtchn for notifications to/from device model */
- uint16_t _pad0;
- uint8_t state:4;
- uint8_t data_is_ptr:1; /* if 1, data above is the guest paddr
- * of the real data to use. */
- uint8_t dir:1; /* 1=read, 0=write */
- uint8_t df:1;
- uint8_t _pad1:1;
- uint8_t type; /* I/O type */
-};
-typedef struct ioreq ioreq_t;
-
-struct shared_iopage {
- struct ioreq vcpu_ioreq[1];
-};
-typedef struct shared_iopage shared_iopage_t;
-
-struct buf_ioreq {
- uint8_t type; /* I/O type */
- uint8_t pad:1;
- uint8_t dir:1; /* 1=read, 0=write */
- uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
- uint32_t addr:20;/* physical address */
- uint32_t data; /* data */
-};
-typedef struct buf_ioreq buf_ioreq_t;
-
-#define IOREQ_BUFFER_SLOT_NUM 511 /* 8 bytes each, plus 2 4-byte indexes */
-struct buffered_iopage {
- unsigned int read_pointer;
- unsigned int write_pointer;
- buf_ioreq_t buf_ioreq[IOREQ_BUFFER_SLOT_NUM];
-}; /* NB. Size of this structure must be no greater than one page. */
-typedef struct buffered_iopage buffered_iopage_t;
-
-/*
- * ACPI Control/Event register locations. Location is controlled by a
- * version number in HVM_PARAM_ACPI_IOPORTS_LOCATION.
- */
-
-/* Version 0 (default): Traditional Xen locations. */
-#define ACPI_PM1A_EVT_BLK_ADDRESS_V0 0x1f40
-#define ACPI_PM1A_CNT_BLK_ADDRESS_V0 (ACPI_PM1A_EVT_BLK_ADDRESS_V0 + 0x04)
-#define ACPI_PM_TMR_BLK_ADDRESS_V0 (ACPI_PM1A_EVT_BLK_ADDRESS_V0 + 0x08)
-#define ACPI_GPE0_BLK_ADDRESS_V0 (ACPI_PM_TMR_BLK_ADDRESS_V0 + 0x20)
-#define ACPI_GPE0_BLK_LEN_V0 0x08
-
-/* Version 1: Locations preferred by modern Qemu. */
-#define ACPI_PM1A_EVT_BLK_ADDRESS_V1 0xb000
-#define ACPI_PM1A_CNT_BLK_ADDRESS_V1 (ACPI_PM1A_EVT_BLK_ADDRESS_V1 + 0x04)
-#define ACPI_PM_TMR_BLK_ADDRESS_V1 (ACPI_PM1A_EVT_BLK_ADDRESS_V1 + 0x08)
-#define ACPI_GPE0_BLK_ADDRESS_V1 0xafe0
-#define ACPI_GPE0_BLK_LEN_V1 0x04
-
-/* Compatibility definitions for the default location (version 0). */
-#define ACPI_PM1A_EVT_BLK_ADDRESS ACPI_PM1A_EVT_BLK_ADDRESS_V0
-#define ACPI_PM1A_CNT_BLK_ADDRESS ACPI_PM1A_CNT_BLK_ADDRESS_V0
-#define ACPI_PM_TMR_BLK_ADDRESS ACPI_PM_TMR_BLK_ADDRESS_V0
-#define ACPI_GPE0_BLK_ADDRESS ACPI_GPE0_BLK_ADDRESS_V0
-#define ACPI_GPE0_BLK_LEN ACPI_GPE0_BLK_LEN_V0
-
-
-#endif /* _IOREQ_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
-#define __XEN_PUBLIC_HVM_PARAMS_H__
-
-#include "hvm_op.h"
-
-/*
- * Parameter space for HVMOP_{set,get}_param.
- */
-
-/*
- * How should CPU0 event-channel notifications be delivered?
- * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
- * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
- * Domain = val[47:32], Bus = val[31:16],
- * DevFn = val[15: 8], IntX = val[ 1: 0]
- * val[63:56] == 2: val[7:0] is a vector number, check for
- * XENFEAT_hvm_callback_vector to know if this delivery
- * method is available.
- * If val == 0 then CPU0 event-channel notifications are not delivered.
- */
-#define HVM_PARAM_CALLBACK_IRQ 0
-
-/*
- * These are not used by Xen. They are here for convenience of HVM-guest
- * xenbus implementations.
- */
-#define HVM_PARAM_STORE_PFN 1
-#define HVM_PARAM_STORE_EVTCHN 2
-
-#define HVM_PARAM_PAE_ENABLED 4
-
-#define HVM_PARAM_IOREQ_PFN 5
-
-#define HVM_PARAM_BUFIOREQ_PFN 6
-#define HVM_PARAM_BUFIOREQ_EVTCHN 26
-
-#if defined(__i386__) || defined(__x86_64__)
-
-/*
- * Viridian enlightenments
- *
- * (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx)
- *
- * To expose viridian enlightenments to the guest set this parameter
- * to the desired feature mask. The base feature set must be present
- * in any valid feature mask.
- */
-#define HVM_PARAM_VIRIDIAN 9
-
-/* Base+Freq viridian feature sets:
- *
- * - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL)
- * - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
- * - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX)
- * - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
- * HV_X64_MSR_APIC_FREQUENCY)
- */
-#define _HVMPV_base_freq 0
-#define HVMPV_base_freq (1 << _HVMPV_base_freq)
-
-/* Feature set modifications */
-
-/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
- * HV_X64_MSR_APIC_FREQUENCY).
- * This modification restores the viridian feature set to the
- * original 'base' set exposed in releases prior to Xen 4.4.
- */
-#define _HVMPV_no_freq 1
-#define HVMPV_no_freq (1 << _HVMPV_no_freq)
-
-/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */
-#define _HVMPV_time_ref_count 2
-#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count)
-
-/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */
-#define _HVMPV_reference_tsc 3
-#define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc)
-
-#define HVMPV_feature_mask \
- (HVMPV_base_freq | \
- HVMPV_no_freq | \
- HVMPV_time_ref_count | \
- HVMPV_reference_tsc)
-
-#endif
-
-/*
- * Set mode for virtual timers (currently x86 only):
- * delay_for_missed_ticks (default):
- * Do not advance a vcpu's time beyond the correct delivery time for
- * interrupts that have been missed due to preemption. Deliver missed
- * interrupts when the vcpu is rescheduled and advance the vcpu's virtual
- * time stepwise for each one.
- * no_delay_for_missed_ticks:
- * As above, missed interrupts are delivered, but guest time always tracks
- * wallclock (i.e., real) time while doing so.
- * no_missed_ticks_pending:
- * No missed interrupts are held pending. Instead, to ensure ticks are
- * delivered at some non-zero rate, if we detect missed ticks then the
- * internal tick alarm is not disabled if the VCPU is preempted during the
- * next tick period.
- * one_missed_tick_pending:
- * Missed interrupts are collapsed together and delivered as one 'late tick'.
- * Guest time always tracks wallclock (i.e., real) time.
- */
-#define HVM_PARAM_TIMER_MODE 10
-#define HVMPTM_delay_for_missed_ticks 0
-#define HVMPTM_no_delay_for_missed_ticks 1
-#define HVMPTM_no_missed_ticks_pending 2
-#define HVMPTM_one_missed_tick_pending 3
-
-/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
-#define HVM_PARAM_HPET_ENABLED 11
-
-/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
-#define HVM_PARAM_IDENT_PT 12
-
-/* Device Model domain, defaults to 0. */
-#define HVM_PARAM_DM_DOMAIN 13
-
-/* ACPI S state: currently support S0 and S3 on x86. */
-#define HVM_PARAM_ACPI_S_STATE 14
-
-/* TSS used on Intel when CR0.PE=0. */
-#define HVM_PARAM_VM86_TSS 15
-
-/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
-#define HVM_PARAM_VPT_ALIGN 16
-
-/* Console debug shared memory ring and event channel */
-#define HVM_PARAM_CONSOLE_PFN 17
-#define HVM_PARAM_CONSOLE_EVTCHN 18
-
-/*
- * Select location of ACPI PM1a and TMR control blocks. Currently two locations
- * are supported, specified by version 0 or 1 in this parameter:
- * - 0: default, use the old addresses
- * PM1A_EVT == 0x1f40; PM1A_CNT == 0x1f44; PM_TMR == 0x1f48
- * - 1: use the new default qemu addresses
- * PM1A_EVT == 0xb000; PM1A_CNT == 0xb004; PM_TMR == 0xb008
- * You can find these address definitions in <hvm/ioreq.h>
- */
-#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
-
-/* Enable blocking memory events, async or sync (pause vcpu until response)
- * onchangeonly indicates messages only on a change of value */
-#define HVM_PARAM_MEMORY_EVENT_CR0 20
-#define HVM_PARAM_MEMORY_EVENT_CR3 21
-#define HVM_PARAM_MEMORY_EVENT_CR4 22
-#define HVM_PARAM_MEMORY_EVENT_INT3 23
-#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25
-#define HVM_PARAM_MEMORY_EVENT_MSR 30
-
-#define HVMPME_MODE_MASK (3 << 0)
-#define HVMPME_mode_disabled 0
-#define HVMPME_mode_async 1
-#define HVMPME_mode_sync 2
-#define HVMPME_onchangeonly (1 << 2)
-
-/* Boolean: Enable nestedhvm (hvm only) */
-#define HVM_PARAM_NESTEDHVM 24
-
-/* Params for the mem event rings */
-#define HVM_PARAM_PAGING_RING_PFN 27
-#define HVM_PARAM_ACCESS_RING_PFN 28
-#define HVM_PARAM_SHARING_RING_PFN 29
-
-/* SHUTDOWN_* action in case of a triple fault */
-#define HVM_PARAM_TRIPLE_FAULT_REASON 31
-
-#define HVM_PARAM_IOREQ_SERVER_PFN 32
-#define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33
-
-/* Location of the VM Generation ID in guest physical address space. */
-#define HVM_PARAM_VM_GENERATION_ID_ADDR 34
-
-#define HVM_NR_PARAMS 35
-
-#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
+++ /dev/null
-/*
- * pvdrivers.h: Register of PV drivers product numbers.
- * Copyright (c) 2012, Citrix Systems Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _XEN_PUBLIC_PVDRIVERS_H_
-#define _XEN_PUBLIC_PVDRIVERS_H_
-
-/*
- * This is the master registry of product numbers for
- * PV drivers.
- * If you need a new product number allocating, please
- * post to xen-devel@lists.xensource.com. You should NOT use
- * a product number without allocating one.
- * If you maintain a separate versioning and distribution path
- * for PV drivers you should have a separate product number so
- * that your drivers can be separated from others.
- *
- * During development, you may use the product ID to
- * indicate a driver which is yet to be released.
- */
-
-#define PVDRIVERS_PRODUCT_LIST(EACH) \
- EACH("xensource-windows", 0x0001) /* Citrix */ \
- EACH("gplpv-windows", 0x0002) /* James Harper */ \
- EACH("linux", 0x0003) \
- EACH("xenserver-windows-v7.0+", 0x0004) /* Citrix */ \
- EACH("xenserver-windows-v7.2+", 0x0005) /* Citrix */ \
- EACH("experimental", 0xffff)
-
-#endif /* _XEN_PUBLIC_PVDRIVERS_H_ */
+++ /dev/null
-/*
- * hvm/save.h
- *
- * Structure definitions for HVM state that is held by Xen and must
- * be saved along with the domain's memory and device-model state.
- *
- * Copyright (c) 2007 XenSource Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_HVM_SAVE_H__
-#define __XEN_PUBLIC_HVM_SAVE_H__
-
-/*
- * Structures in this header *must* have the same layout in 32bit
- * and 64bit environments: this means that all fields must be explicitly
- * sized types and aligned to their sizes, and the structs must be
- * a multiple of eight bytes long.
- *
- * Only the state necessary for saving and restoring (i.e. fields
- * that are analogous to actual hardware state) should go in this file.
- * Internal mechanisms should be kept in Xen-private headers.
- */
-
-#if !defined(__GNUC__) || defined(__STRICT_ANSI__)
-#error "Anonymous structs/unions are a GNU extension."
-#endif
-
-/*
- * Each entry is preceded by a descriptor giving its type and length
- */
-struct hvm_save_descriptor {
- uint16_t typecode; /* Used to demux the various types below */
- uint16_t instance; /* Further demux within a type */
- uint32_t length; /* In bytes, *not* including this descriptor */
-};
-
-
-/*
- * Each entry has a datatype associated with it: for example, the CPU state
- * is saved as a HVM_SAVE_TYPE(CPU), which has HVM_SAVE_LENGTH(CPU),
- * and is identified by a descriptor with typecode HVM_SAVE_CODE(CPU).
- * DECLARE_HVM_SAVE_TYPE binds these things together with some type-system
- * ugliness.
- */
-
-#ifdef __XEN__
-# define DECLARE_HVM_SAVE_TYPE_COMPAT(_x, _code, _type, _ctype, _fix) \
- static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { return _fix(h); } \
- struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}; \
- struct __HVM_SAVE_TYPE_COMPAT_##_x { _ctype t; }
-
-# include <xen/lib.h> /* BUG() */
-# define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \
- static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { BUG(); return -1; } \
- struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}; \
- struct __HVM_SAVE_TYPE_COMPAT_##_x { _type t; }
-#else
-# define DECLARE_HVM_SAVE_TYPE_COMPAT(_x, _code, _type, _ctype, _fix) \
- struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}
-
-# define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \
- struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}
-#endif
-
-#define HVM_SAVE_TYPE(_x) typeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->t)
-#define HVM_SAVE_LENGTH(_x) (sizeof (HVM_SAVE_TYPE(_x)))
-#define HVM_SAVE_CODE(_x) (sizeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->c))
-
-#ifdef __XEN__
-# define HVM_SAVE_TYPE_COMPAT(_x) typeof (((struct __HVM_SAVE_TYPE_COMPAT_##_x *)(0))->t)
-# define HVM_SAVE_LENGTH_COMPAT(_x) (sizeof (HVM_SAVE_TYPE_COMPAT(_x)))
-
-# define HVM_SAVE_HAS_COMPAT(_x) (sizeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->cpt)-1)
-# define HVM_SAVE_FIX_COMPAT(_x, _dst) __HVM_SAVE_FIX_COMPAT_##_x(_dst)
-#endif
-
-/*
- * The series of save records is teminated by a zero-type, zero-length
- * descriptor.
- */
-
-struct hvm_save_end {};
-DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm_save_end);
-
-#if defined(__i386__) || defined(__x86_64__)
-#include "../arch-x86/hvm/save.h"
-#elif defined(__arm__) || defined(__aarch64__)
-#include "../arch-arm/hvm/save.h"
-#else
-#error "unsupported architecture"
-#endif
-
-#endif /* __XEN_PUBLIC_HVM_SAVE_H__ */
+++ /dev/null
-/******************************************************************************
- * blkif.h
- *
- * Unified block-device I/O interface for Xen guest OSes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2003-2004, Keir Fraser
- * Copyright (c) 2012, Spectra Logic Corporation
- */
-
-#ifndef __XEN_PUBLIC_IO_BLKIF_H__
-#define __XEN_PUBLIC_IO_BLKIF_H__
-
-#include "ring.h"
-#include "../grant_table.h"
-
-/*
- * Front->back notifications: When enqueuing a new request, sending a
- * notification can be made conditional on req_event (i.e., the generic
- * hold-off mechanism provided by the ring macros). Backends must set
- * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
- *
- * Back->front notifications: When enqueuing a new response, sending a
- * notification can be made conditional on rsp_event (i.e., the generic
- * hold-off mechanism provided by the ring macros). Frontends must set
- * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
- */
-
-#ifndef blkif_vdev_t
-#define blkif_vdev_t uint16_t
-#endif
-#define blkif_sector_t uint64_t
-
-/*
- * Feature and Parameter Negotiation
- * =================================
- * The two halves of a Xen block driver utilize nodes within the XenStore to
- * communicate capabilities and to negotiate operating parameters. This
- * section enumerates these nodes which reside in the respective front and
- * backend portions of the XenStore, following the XenBus convention.
- *
- * All data in the XenStore is stored as strings. Nodes specifying numeric
- * values are encoded in decimal. Integer value ranges listed below are
- * expressed as fixed sized integer types capable of storing the conversion
- * of a properly formated node string, without loss of information.
- *
- * Any specified default value is in effect if the corresponding XenBus node
- * is not present in the XenStore.
- *
- * XenStore nodes in sections marked "PRIVATE" are solely for use by the
- * driver side whose XenBus tree contains them.
- *
- * XenStore nodes marked "DEPRECATED" in their notes section should only be
- * used to provide interoperability with legacy implementations.
- *
- * See the XenBus state transition diagram below for details on when XenBus
- * nodes must be published and when they can be queried.
- *
- *****************************************************************************
- * Backend XenBus Nodes
- *****************************************************************************
- *
- *------------------ Backend Device Identification (PRIVATE) ------------------
- *
- * mode
- * Values: "r" (read only), "w" (writable)
- *
- * The read or write access permissions to the backing store to be
- * granted to the frontend.
- *
- * params
- * Values: string
- *
- * A free formatted string providing sufficient information for the
- * backend driver to open the backing device. (e.g. the path to the
- * file or block device representing the backing store.)
- *
- * type
- * Values: "file", "phy", "tap"
- *
- * The type of the backing device/object.
- *
- *
- * direct-io-safe
- * Values: 0/1 (boolean)
- * Default Value: 0
- *
- * The underlying storage is not affected by the direct IO memory
- * lifetime bug. See:
- * http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
- *
- * Therefore this option gives the backend permission to use
- * O_DIRECT, notwithstanding that bug.
- *
- * That is, if this option is enabled, use of O_DIRECT is safe,
- * in circumstances where we would normally have avoided it as a
- * workaround for that bug. This option is not relevant for all
- * backends, and even not necessarily supported for those for
- * which it is relevant. A backend which knows that it is not
- * affected by the bug can ignore this option.
- *
- * This option doesn't require a backend to use O_DIRECT, so it
- * should not be used to try to control the caching behaviour.
- *
- *--------------------------------- Features ---------------------------------
- *
- * feature-barrier
- * Values: 0/1 (boolean)
- * Default Value: 0
- *
- * A value of "1" indicates that the backend can process requests
- * containing the BLKIF_OP_WRITE_BARRIER request opcode. Requests
- * of this type may still be returned at any time with the
- * BLKIF_RSP_EOPNOTSUPP result code.
- *
- * feature-flush-cache
- * Values: 0/1 (boolean)
- * Default Value: 0
- *
- * A value of "1" indicates that the backend can process requests
- * containing the BLKIF_OP_FLUSH_DISKCACHE request opcode. Requests
- * of this type may still be returned at any time with the
- * BLKIF_RSP_EOPNOTSUPP result code.
- *
- * feature-discard
- * Values: 0/1 (boolean)
- * Default Value: 0
- *
- * A value of "1" indicates that the backend can process requests
- * containing the BLKIF_OP_DISCARD request opcode. Requests
- * of this type may still be returned at any time with the
- * BLKIF_RSP_EOPNOTSUPP result code.
- *
- * feature-persistent
- * Values: 0/1 (boolean)
- * Default Value: 0
- * Notes: 7
- *
- * A value of "1" indicates that the backend can keep the grants used
- * by the frontend driver mapped, so the same set of grants should be
- * used in all transactions. The maximum number of grants the backend
- * can map persistently depends on the implementation, but ideally it
- * should be RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. Using this
- * feature the backend doesn't need to unmap each grant, preventing
- * costly TLB flushes. The backend driver should only map grants
- * persistently if the frontend supports it. If a backend driver chooses
- * to use the persistent protocol when the frontend doesn't support it,
- * it will probably hit the maximum number of persistently mapped grants
- * (due to the fact that the frontend won't be reusing the same grants),
- * and fall back to non-persistent mode. Backend implementations may
- * shrink or expand the number of persistently mapped grants without
- * notifying the frontend depending on memory constraints (this might
- * cause a performance degradation).
- *
- * If a backend driver wants to limit the maximum number of persistently
- * mapped grants to a value less than RING_SIZE *
- * BLKIF_MAX_SEGMENTS_PER_REQUEST a LRU strategy should be used to
- * discard the grants that are less commonly used. Using a LRU in the
- * backend driver paired with a LIFO queue in the frontend will
- * allow us to have better performance in this scenario.
- *
- *----------------------- Request Transport Parameters ------------------------
- *
- * max-ring-page-order
- * Values: <uint32_t>
- * Default Value: 0
- * Notes: 1, 3
- *
- * The maximum supported size of the request ring buffer in units of
- * lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages,
- * etc.).
- *
- * max-ring-pages
- * Values: <uint32_t>
- * Default Value: 1
- * Notes: DEPRECATED, 2, 3
- *
- * The maximum supported size of the request ring buffer in units of
- * machine pages. The value must be a power of 2.
- *
- *------------------------- Backend Device Properties -------------------------
- *
- * discard-enable
- * Values: 0/1 (boolean)
- * Default Value: 1
- *
- * This optional property, set by the toolstack, instructs the backend
- * to offer discard to the frontend. If the property is missing the
- * backend should offer discard if the backing storage actually supports
- * it. This optional property, set by the toolstack, requests that the
- * backend offer, or not offer, discard to the frontend.
- *
- * discard-alignment
- * Values: <uint32_t>
- * Default Value: 0
- * Notes: 4, 5
- *
- * The offset, in bytes from the beginning of the virtual block device,
- * to the first, addressable, discard extent on the underlying device.
- *
- * discard-granularity
- * Values: <uint32_t>
- * Default Value: <"sector-size">
- * Notes: 4
- *
- * The size, in bytes, of the individually addressable discard extents
- * of the underlying device.
- *
- * discard-secure
- * Values: 0/1 (boolean)
- * Default Value: 0
- * Notes: 10
- *
- * A value of "1" indicates that the backend can process BLKIF_OP_DISCARD
- * requests with the BLKIF_DISCARD_SECURE flag set.
- *
- * info
- * Values: <uint32_t> (bitmap)
- *
- * A collection of bit flags describing attributes of the backing
- * device. The VDISK_* macros define the meaning of each bit
- * location.
- *
- * sector-size
- * Values: <uint32_t>
- *
- * The logical sector size, in bytes, of the backend device.
- *
- * physical-sector-size
- * Values: <uint32_t>
- *
- * The physical sector size, in bytes, of the backend device.
- *
- * sectors
- * Values: <uint64_t>
- *
- * The size of the backend device, expressed in units of its logical
- * sector size ("sector-size").
- *
- *****************************************************************************
- * Frontend XenBus Nodes
- *****************************************************************************
- *
- *----------------------- Request Transport Parameters -----------------------
- *
- * event-channel
- * Values: <uint32_t>
- *
- * The identifier of the Xen event channel used to signal activity
- * in the ring buffer.
- *
- * ring-ref
- * Values: <uint32_t>
- * Notes: 6
- *
- * The Xen grant reference granting permission for the backend to map
- * the sole page in a single page sized ring buffer.
- *
- * ring-ref%u
- * Values: <uint32_t>
- * Notes: 6
- *
- * For a frontend providing a multi-page ring, a "number of ring pages"
- * sized list of nodes, each containing a Xen grant reference granting
- * permission for the backend to map the page of the ring located
- * at page index "%u". Page indexes are zero based.
- *
- * protocol
- * Values: string (XEN_IO_PROTO_ABI_*)
- * Default Value: XEN_IO_PROTO_ABI_NATIVE
- *
- * The machine ABI rules governing the format of all ring request and
- * response structures.
- *
- * ring-page-order
- * Values: <uint32_t>
- * Default Value: 0
- * Maximum Value: MAX(ffs(max-ring-pages) - 1, max-ring-page-order)
- * Notes: 1, 3
- *
- * The size of the frontend allocated request ring buffer in units
- * of lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages,
- * etc.).
- *
- * num-ring-pages
- * Values: <uint32_t>
- * Default Value: 1
- * Maximum Value: MAX(max-ring-pages,(0x1 << max-ring-page-order))
- * Notes: DEPRECATED, 2, 3
- *
- * The size of the frontend allocated request ring buffer in units of
- * machine pages. The value must be a power of 2.
- *
- * feature-persistent
- * Values: 0/1 (boolean)
- * Default Value: 0
- * Notes: 7, 8, 9
- *
- * A value of "1" indicates that the frontend will reuse the same grants
- * for all transactions, allowing the backend to map them with write
- * access (even when it should be read-only). If the frontend hits the
- * maximum number of allowed persistently mapped grants, it can fallback
- * to non persistent mode. This will cause a performance degradation,
- * since the the backend driver will still try to map those grants
- * persistently. Since the persistent grants protocol is compatible with
- * the previous protocol, a frontend driver can choose to work in
- * persistent mode even when the backend doesn't support it.
- *
- * It is recommended that the frontend driver stores the persistently
- * mapped grants in a LIFO queue, so a subset of all persistently mapped
- * grants gets used commonly. This is done in case the backend driver
- * decides to limit the maximum number of persistently mapped grants
- * to a value less than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST.
- *
- *------------------------- Virtual Device Properties -------------------------
- *
- * device-type
- * Values: "disk", "cdrom", "floppy", etc.
- *
- * virtual-device
- * Values: <uint32_t>
- *
- * A value indicating the physical device to virtualize within the
- * frontend's domain. (e.g. "The first ATA disk", "The third SCSI
- * disk", etc.)
- *
- * See docs/misc/vbd-interface.txt for details on the format of this
- * value.
- *
- * Notes
- * -----
- * (1) Multi-page ring buffer scheme first developed in the Citrix XenServer
- * PV drivers.
- * (2) Multi-page ring buffer scheme first used in some RedHat distributions
- * including a distribution deployed on certain nodes of the Amazon
- * EC2 cluster.
- * (3) Support for multi-page ring buffers was implemented independently,
- * in slightly different forms, by both Citrix and RedHat/Amazon.
- * For full interoperability, block front and backends should publish
- * identical ring parameters, adjusted for unit differences, to the
- * XenStore nodes used in both schemes.
- * (4) Devices that support discard functionality may internally allocate space
- * (discardable extents) in units that are larger than the exported logical
- * block size. If the backing device has such discardable extents the
- * backend should provide both discard-granularity and discard-alignment.
- * Providing just one of the two may be considered an error by the frontend.
- * Backends supporting discard should include discard-granularity and
- * discard-alignment even if it supports discarding individual sectors.
- * Frontends should assume discard-alignment == 0 and discard-granularity
- * == sector size if these keys are missing.
- * (5) The discard-alignment parameter allows a physical device to be
- * partitioned into virtual devices that do not necessarily begin or
- * end on a discardable extent boundary.
- * (6) When there is only a single page allocated to the request ring,
- * 'ring-ref' is used to communicate the grant reference for this
- * page to the backend. When using a multi-page ring, the 'ring-ref'
- * node is not created. Instead 'ring-ref0' - 'ring-refN' are used.
- * (7) When using persistent grants data has to be copied from/to the page
- * where the grant is currently mapped. The overhead of doing this copy
- * however doesn't suppress the speed improvement of not having to unmap
- * the grants.
- * (8) The frontend driver has to allow the backend driver to map all grants
- * with write access, even when they should be mapped read-only, since
- * further requests may reuse these grants and require write permissions.
- * (9) Linux implementation doesn't have a limit on the maximum number of
- * grants that can be persistently mapped in the frontend driver, but
- * due to the frontent driver implementation it should never be bigger
- * than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST.
- *(10) The discard-secure property may be present and will be set to 1 if the
- * backing device supports secure discard.
- */
-
-/*
- * STATE DIAGRAMS
- *
- *****************************************************************************
- * Startup *
- *****************************************************************************
- *
- * Tool stack creates front and back nodes with state XenbusStateInitialising.
- *
- * Front Back
- * ================================= =====================================
- * XenbusStateInitialising XenbusStateInitialising
- * o Query virtual device o Query backend device identification
- * properties. data.
- * o Setup OS device instance. o Open and validate backend device.
- * o Publish backend features and
- * transport parameters.
- * |
- * |
- * V
- * XenbusStateInitWait
- *
- * o Query backend features and
- * transport parameters.
- * o Allocate and initialize the
- * request ring.
- * o Publish transport parameters
- * that will be in effect during
- * this connection.
- * |
- * |
- * V
- * XenbusStateInitialised
- *
- * o Query frontend transport parameters.
- * o Connect to the request ring and
- * event channel.
- * o Publish backend device properties.
- * |
- * |
- * V
- * XenbusStateConnected
- *
- * o Query backend device properties.
- * o Finalize OS virtual device
- * instance.
- * |
- * |
- * V
- * XenbusStateConnected
- *
- * Note: Drivers that do not support any optional features, or the negotiation
- * of transport parameters, can skip certain states in the state machine:
- *
- * o A frontend may transition to XenbusStateInitialised without
- * waiting for the backend to enter XenbusStateInitWait. In this
- * case, default transport parameters are in effect and any
- * transport parameters published by the frontend must contain
- * their default values.
- *
- * o A backend may transition to XenbusStateInitialised, bypassing
- * XenbusStateInitWait, without waiting for the frontend to first
- * enter the XenbusStateInitialised state. In this case, default
- * transport parameters are in effect and any transport parameters
- * published by the backend must contain their default values.
- *
- * Drivers that support optional features and/or transport parameter
- * negotiation must tolerate these additional state transition paths.
- * In general this means performing the work of any skipped state
- * transition, if it has not already been performed, in addition to the
- * work associated with entry into the current state.
- */
-
-/*
- * REQUEST CODES.
- */
-#define BLKIF_OP_READ 0
-#define BLKIF_OP_WRITE 1
-/*
- * All writes issued prior to a request with the BLKIF_OP_WRITE_BARRIER
- * operation code ("barrier request") must be completed prior to the
- * execution of the barrier request. All writes issued after the barrier
- * request must not execute until after the completion of the barrier request.
- *
- * Optional. See "feature-barrier" XenBus node documentation above.
- */
-#define BLKIF_OP_WRITE_BARRIER 2
-/*
- * Commit any uncommitted contents of the backing device's volatile cache
- * to stable storage.
- *
- * Optional. See "feature-flush-cache" XenBus node documentation above.
- */
-#define BLKIF_OP_FLUSH_DISKCACHE 3
-/*
- * Used in SLES sources for device specific command packet
- * contained within the request. Reserved for that purpose.
- */
-#define BLKIF_OP_RESERVED_1 4
-/*
- * Indicate to the backend device that a region of storage is no longer in
- * use, and may be discarded at any time without impact to the client. If
- * the BLKIF_DISCARD_SECURE flag is set on the request, all copies of the
- * discarded region on the device must be rendered unrecoverable before the
- * command returns.
- *
- * This operation is analogous to performing a trim (ATA) or unamp (SCSI),
- * command on a native device.
- *
- * More information about trim/unmap operations can be found at:
- * http://t13.org/Documents/UploadedDocuments/docs2008/
- * e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
- * http://www.seagate.com/staticfiles/support/disc/manuals/
- * Interface%20manuals/100293068c.pdf
- *
- * Optional. See "feature-discard", "discard-alignment",
- * "discard-granularity", and "discard-secure" in the XenBus node
- * documentation above.
- */
-#define BLKIF_OP_DISCARD 5
-
-/*
- * Recognized if "feature-max-indirect-segments" in present in the backend
- * xenbus info. The "feature-max-indirect-segments" node contains the maximum
- * number of segments allowed by the backend per request. If the node is
- * present, the frontend might use blkif_request_indirect structs in order to
- * issue requests with more than BLKIF_MAX_SEGMENTS_PER_REQUEST (11). The
- * maximum number of indirect segments is fixed by the backend, but the
- * frontend can issue requests with any number of indirect segments as long as
- * it's less than the number provided by the backend. The indirect_grefs field
- * in blkif_request_indirect should be filled by the frontend with the
- * grant references of the pages that are holding the indirect segments.
- * These pages are filled with an array of blkif_request_segment that hold the
- * information about the segments. The number of indirect pages to use is
- * determined by the number of segments an indirect request contains. Every
- * indirect page can contain a maximum of
- * (PAGE_SIZE / sizeof(struct blkif_request_segment)) segments, so to
- * calculate the number of indirect pages to use we have to do
- * ceil(indirect_segments / (PAGE_SIZE / sizeof(struct blkif_request_segment))).
- *
- * If a backend does not recognize BLKIF_OP_INDIRECT, it should *not*
- * create the "feature-max-indirect-segments" node!
- */
-#define BLKIF_OP_INDIRECT 6
-
-/*
- * Maximum scatter/gather segments per request.
- * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
- * NB. This could be 12 if the ring indexes weren't stored in the same page.
- */
-#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
-
-/*
- * Maximum number of indirect pages to use per request.
- */
-#define BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST 8
-
-/*
- * NB. first_sect and last_sect in blkif_request_segment, as well as
- * sector_number in blkif_request, are always expressed in 512-byte units.
- * However they must be properly aligned to the real sector size of the
- * physical disk, which is reported in the "physical-sector-size" node in
- * the backend xenbus info. Also the xenbus "sectors" node is expressed in
- * 512-byte units.
- */
-struct blkif_request_segment {
- grant_ref_t gref; /* reference to I/O buffer frame */
- /* @first_sect: first sector in frame to transfer (inclusive). */
- /* @last_sect: last sector in frame to transfer (inclusive). */
- uint8_t first_sect, last_sect;
-};
-
-/*
- * Starting ring element for any I/O request.
- */
-struct blkif_request {
- uint8_t operation; /* BLKIF_OP_??? */
- uint8_t nr_segments; /* number of segments */
- blkif_vdev_t handle; /* only for read/write requests */
- uint64_t id; /* private guest value, echoed in resp */
- blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
-typedef struct blkif_request blkif_request_t;
-
-/*
- * Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD
- * sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request)
- */
-struct blkif_request_discard {
- uint8_t operation; /* BLKIF_OP_DISCARD */
- uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */
-#define BLKIF_DISCARD_SECURE (1<<0) /* ignored if discard-secure=0 */
- blkif_vdev_t handle; /* same as for read/write requests */
- uint64_t id; /* private guest value, echoed in resp */
- blkif_sector_t sector_number;/* start sector idx on disk */
- uint64_t nr_sectors; /* number of contiguous sectors to discard*/
-};
-typedef struct blkif_request_discard blkif_request_discard_t;
-
-struct blkif_request_indirect {
- uint8_t operation; /* BLKIF_OP_INDIRECT */
- uint8_t indirect_op; /* BLKIF_OP_{READ/WRITE} */
- uint16_t nr_segments; /* number of segments */
- uint64_t id; /* private guest value, echoed in resp */
- blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- blkif_vdev_t handle; /* same as for read/write requests */
- grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
-#ifdef __i386__
- uint64_t pad; /* Make it 64 byte aligned on i386 */
-#endif
-};
-typedef struct blkif_request_indirect blkif_request_indirect_t;
-
-struct blkif_response {
- uint64_t id; /* copied from request */
- uint8_t operation; /* copied from request */
- int16_t status; /* BLKIF_RSP_??? */
-};
-typedef struct blkif_response blkif_response_t;
-
-/*
- * STATUS RETURN CODES.
- */
- /* Operation not supported (only happens on barrier writes). */
-#define BLKIF_RSP_EOPNOTSUPP -2
- /* Operation failed for some unspecified reason (-EIO). */
-#define BLKIF_RSP_ERROR -1
- /* Operation completed successfully. */
-#define BLKIF_RSP_OKAY 0
-
-/*
- * Generate blkif ring structures and types.
- */
-DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
-
-#define VDISK_CDROM 0x1
-#define VDISK_REMOVABLE 0x2
-#define VDISK_READONLY 0x4
-
-#endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * console.h
- *
- * Console I/O interface for Xen guest OSes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Keir Fraser
- */
-
-#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
-#define __XEN_PUBLIC_IO_CONSOLE_H__
-
-typedef uint32_t XENCONS_RING_IDX;
-
-#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
-
-struct xencons_interface {
- char in[1024];
- char out[2048];
- XENCONS_RING_IDX in_cons, in_prod;
- XENCONS_RING_IDX out_cons, out_prod;
-};
-
-#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * fbif.h -- Xen virtual frame buffer device
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
- * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
- */
-
-#ifndef __XEN_PUBLIC_IO_FBIF_H__
-#define __XEN_PUBLIC_IO_FBIF_H__
-
-/* Out events (frontend -> backend) */
-
-/*
- * Out events may be sent only when requested by backend, and receipt
- * of an unknown out event is an error.
- */
-
-/* Event type 1 currently not used */
-/*
- * Framebuffer update notification event
- * Capable frontend sets feature-update in xenstore.
- * Backend requests it by setting request-update in xenstore.
- */
-#define XENFB_TYPE_UPDATE 2
-
-struct xenfb_update
-{
- uint8_t type; /* XENFB_TYPE_UPDATE */
- int32_t x; /* source x */
- int32_t y; /* source y */
- int32_t width; /* rect width */
- int32_t height; /* rect height */
-};
-
-/*
- * Framebuffer resize notification event
- * Capable backend sets feature-resize in xenstore.
- */
-#define XENFB_TYPE_RESIZE 3
-
-struct xenfb_resize
-{
- uint8_t type; /* XENFB_TYPE_RESIZE */
- int32_t width; /* width in pixels */
- int32_t height; /* height in pixels */
- int32_t stride; /* stride in bytes */
- int32_t depth; /* depth in bits */
- int32_t offset; /* offset of the framebuffer in bytes */
-};
-
-#define XENFB_OUT_EVENT_SIZE 40
-
-union xenfb_out_event
-{
- uint8_t type;
- struct xenfb_update update;
- struct xenfb_resize resize;
- char pad[XENFB_OUT_EVENT_SIZE];
-};
-
-/* In events (backend -> frontend) */
-
-/*
- * Frontends should ignore unknown in events.
- */
-
-/*
- * Framebuffer refresh period advice
- * Backend sends it to advise the frontend their preferred period of
- * refresh. Frontends that keep the framebuffer constantly up-to-date
- * just ignore it. Frontends that use the advice should immediately
- * refresh the framebuffer (and send an update notification event if
- * those have been requested), then use the update frequency to guide
- * their periodical refreshs.
- */
-#define XENFB_TYPE_REFRESH_PERIOD 1
-#define XENFB_NO_REFRESH 0
-
-struct xenfb_refresh_period
-{
- uint8_t type; /* XENFB_TYPE_UPDATE_PERIOD */
- uint32_t period; /* period of refresh, in ms,
- * XENFB_NO_REFRESH if no refresh is needed */
-};
-
-#define XENFB_IN_EVENT_SIZE 40
-
-union xenfb_in_event
-{
- uint8_t type;
- struct xenfb_refresh_period refresh_period;
- char pad[XENFB_IN_EVENT_SIZE];
-};
-
-/* shared page */
-
-#define XENFB_IN_RING_SIZE 1024
-#define XENFB_IN_RING_LEN (XENFB_IN_RING_SIZE / XENFB_IN_EVENT_SIZE)
-#define XENFB_IN_RING_OFFS 1024
-#define XENFB_IN_RING(page) \
- ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
-#define XENFB_IN_RING_REF(page, idx) \
- (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
-
-#define XENFB_OUT_RING_SIZE 2048
-#define XENFB_OUT_RING_LEN (XENFB_OUT_RING_SIZE / XENFB_OUT_EVENT_SIZE)
-#define XENFB_OUT_RING_OFFS (XENFB_IN_RING_OFFS + XENFB_IN_RING_SIZE)
-#define XENFB_OUT_RING(page) \
- ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
-#define XENFB_OUT_RING_REF(page, idx) \
- (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
-
-struct xenfb_page
-{
- uint32_t in_cons, in_prod;
- uint32_t out_cons, out_prod;
-
- int32_t width; /* the width of the framebuffer (in pixels) */
- int32_t height; /* the height of the framebuffer (in pixels) */
- uint32_t line_length; /* the length of a row of pixels (in bytes) */
- uint32_t mem_length; /* the length of the framebuffer (in bytes) */
- uint8_t depth; /* the depth of a pixel (in bits) */
-
- /*
- * Framebuffer page directory
- *
- * Each directory page holds PAGE_SIZE / sizeof(*pd)
- * framebuffer pages, and can thus map up to PAGE_SIZE *
- * PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
- * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs
- * 64 bit. 256 directories give enough room for a 512 Meg
- * framebuffer with a max resolution of 12,800x10,240. Should
- * be enough for a while with room leftover for expansion.
- */
- unsigned long pd[256];
-};
-
-/*
- * Wart: xenkbd needs to know default resolution. Put it here until a
- * better solution is found, but don't leak it to the backend.
- */
-#ifdef __KERNEL__
-#define XENFB_WIDTH 800
-#define XENFB_HEIGHT 600
-#define XENFB_DEPTH 32
-#endif
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * fsif.h
- *
- * Interface to FS level split device drivers.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2007, Grzegorz Milos, <gm281@cam.ac.uk>.
- */
-
-#ifndef __XEN_PUBLIC_IO_FSIF_H__
-#define __XEN_PUBLIC_IO_FSIF_H__
-
-#include "ring.h"
-#include "../grant_table.h"
-
-#define REQ_FILE_OPEN 1
-#define REQ_FILE_CLOSE 2
-#define REQ_FILE_READ 3
-#define REQ_FILE_WRITE 4
-#define REQ_STAT 5
-#define REQ_FILE_TRUNCATE 6
-#define REQ_REMOVE 7
-#define REQ_RENAME 8
-#define REQ_CREATE 9
-#define REQ_DIR_LIST 10
-#define REQ_CHMOD 11
-#define REQ_FS_SPACE 12
-#define REQ_FILE_SYNC 13
-
-struct fsif_open_request {
- grant_ref_t gref;
-};
-
-struct fsif_close_request {
- uint32_t fd;
-};
-
-struct fsif_read_request {
- uint32_t fd;
- int32_t pad;
- uint64_t len;
- uint64_t offset;
- grant_ref_t grefs[1]; /* Variable length */
-};
-
-struct fsif_write_request {
- uint32_t fd;
- int32_t pad;
- uint64_t len;
- uint64_t offset;
- grant_ref_t grefs[1]; /* Variable length */
-};
-
-struct fsif_stat_request {
- uint32_t fd;
-};
-
-/* This structure is a copy of some fields from stat structure, returned
- * via the ring. */
-struct fsif_stat_response {
- int32_t stat_mode;
- uint32_t stat_uid;
- uint32_t stat_gid;
- int32_t stat_ret;
- int64_t stat_size;
- int64_t stat_atime;
- int64_t stat_mtime;
- int64_t stat_ctime;
-};
-
-struct fsif_truncate_request {
- uint32_t fd;
- int32_t pad;
- int64_t length;
-};
-
-struct fsif_remove_request {
- grant_ref_t gref;
-};
-
-struct fsif_rename_request {
- uint16_t old_name_offset;
- uint16_t new_name_offset;
- grant_ref_t gref;
-};
-
-struct fsif_create_request {
- int8_t directory;
- int8_t pad;
- int16_t pad2;
- int32_t mode;
- grant_ref_t gref;
-};
-
-struct fsif_list_request {
- uint32_t offset;
- grant_ref_t gref;
-};
-
-#define NR_FILES_SHIFT 0
-#define NR_FILES_SIZE 16 /* 16 bits for the number of files mask */
-#define NR_FILES_MASK (((1ULL << NR_FILES_SIZE) - 1) << NR_FILES_SHIFT)
-#define ERROR_SIZE 32 /* 32 bits for the error mask */
-#define ERROR_SHIFT (NR_FILES_SIZE + NR_FILES_SHIFT)
-#define ERROR_MASK (((1ULL << ERROR_SIZE) - 1) << ERROR_SHIFT)
-#define HAS_MORE_SHIFT (ERROR_SHIFT + ERROR_SIZE)
-#define HAS_MORE_FLAG (1ULL << HAS_MORE_SHIFT)
-
-struct fsif_chmod_request {
- uint32_t fd;
- int32_t mode;
-};
-
-struct fsif_space_request {
- grant_ref_t gref;
-};
-
-struct fsif_sync_request {
- uint32_t fd;
-};
-
-
-/* FS operation request */
-struct fsif_request {
- uint8_t type; /* Type of the request */
- uint8_t pad;
- uint16_t id; /* Request ID, copied to the response */
- uint32_t pad2;
- union {
- struct fsif_open_request fopen;
- struct fsif_close_request fclose;
- struct fsif_read_request fread;
- struct fsif_write_request fwrite;
- struct fsif_stat_request fstat;
- struct fsif_truncate_request ftruncate;
- struct fsif_remove_request fremove;
- struct fsif_rename_request frename;
- struct fsif_create_request fcreate;
- struct fsif_list_request flist;
- struct fsif_chmod_request fchmod;
- struct fsif_space_request fspace;
- struct fsif_sync_request fsync;
- } u;
-};
-typedef struct fsif_request fsif_request_t;
-
-/* FS operation response */
-struct fsif_response {
- uint16_t id;
- uint16_t pad1;
- uint32_t pad2;
- union {
- uint64_t ret_val;
- struct fsif_stat_response fstat;
- } u;
-};
-
-typedef struct fsif_response fsif_response_t;
-
-#define FSIF_RING_ENTRY_SIZE 64
-
-#define FSIF_NR_READ_GNTS ((FSIF_RING_ENTRY_SIZE - sizeof(struct fsif_read_request)) / \
- sizeof(grant_ref_t) + 1)
-#define FSIF_NR_WRITE_GNTS ((FSIF_RING_ENTRY_SIZE - sizeof(struct fsif_write_request)) / \
- sizeof(grant_ref_t) + 1)
-
-DEFINE_RING_TYPES(fsif, struct fsif_request, struct fsif_response);
-
-#define STATE_INITIALISED "init"
-#define STATE_READY "ready"
-#define STATE_CLOSING "closing"
-#define STATE_CLOSED "closed"
-
-
-#endif
+++ /dev/null
-/*
- * kbdif.h -- Xen virtual keyboard/mouse
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
- * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
- */
-
-#ifndef __XEN_PUBLIC_IO_KBDIF_H__
-#define __XEN_PUBLIC_IO_KBDIF_H__
-
-/* In events (backend -> frontend) */
-
-/*
- * Frontends should ignore unknown in events.
- */
-
-/* Pointer movement event */
-#define XENKBD_TYPE_MOTION 1
-/* Event type 2 currently not used */
-/* Key event (includes pointer buttons) */
-#define XENKBD_TYPE_KEY 3
-/*
- * Pointer position event
- * Capable backend sets feature-abs-pointer in xenstore.
- * Frontend requests ot instead of XENKBD_TYPE_MOTION by setting
- * request-abs-update in xenstore.
- */
-#define XENKBD_TYPE_POS 4
-
-struct xenkbd_motion
-{
- uint8_t type; /* XENKBD_TYPE_MOTION */
- int32_t rel_x; /* relative X motion */
- int32_t rel_y; /* relative Y motion */
- int32_t rel_z; /* relative Z motion (wheel) */
-};
-
-struct xenkbd_key
-{
- uint8_t type; /* XENKBD_TYPE_KEY */
- uint8_t pressed; /* 1 if pressed; 0 otherwise */
- uint32_t keycode; /* KEY_* from linux/input.h */
-};
-
-struct xenkbd_position
-{
- uint8_t type; /* XENKBD_TYPE_POS */
- int32_t abs_x; /* absolute X position (in FB pixels) */
- int32_t abs_y; /* absolute Y position (in FB pixels) */
- int32_t rel_z; /* relative Z motion (wheel) */
-};
-
-#define XENKBD_IN_EVENT_SIZE 40
-
-union xenkbd_in_event
-{
- uint8_t type;
- struct xenkbd_motion motion;
- struct xenkbd_key key;
- struct xenkbd_position pos;
- char pad[XENKBD_IN_EVENT_SIZE];
-};
-
-/* Out events (frontend -> backend) */
-
-/*
- * Out events may be sent only when requested by backend, and receipt
- * of an unknown out event is an error.
- * No out events currently defined.
- */
-
-#define XENKBD_OUT_EVENT_SIZE 40
-
-union xenkbd_out_event
-{
- uint8_t type;
- char pad[XENKBD_OUT_EVENT_SIZE];
-};
-
-/* shared page */
-
-#define XENKBD_IN_RING_SIZE 2048
-#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
-#define XENKBD_IN_RING_OFFS 1024
-#define XENKBD_IN_RING(page) \
- ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
-#define XENKBD_IN_RING_REF(page, idx) \
- (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
-
-#define XENKBD_OUT_RING_SIZE 1024
-#define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
-#define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
-#define XENKBD_OUT_RING(page) \
- ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
-#define XENKBD_OUT_RING_REF(page, idx) \
- (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
-
-struct xenkbd_page
-{
- uint32_t in_cons, in_prod;
- uint32_t out_cons, out_prod;
-};
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
- *
- * Authors:
- * Rafal Wojtczuk <rafal@invisiblethingslab.com>
- * Daniel De Graaf <dgdegra@tycho.nsa.gov>
- *
- * @section LICENSE
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * @section DESCRIPTION
- *
- * Originally borrowed from the Qubes OS Project, http://www.qubes-os.org,
- * this code has been substantially rewritten to use the gntdev and gntalloc
- * devices instead of raw MFNs and map_foreign_range.
- *
- * This is a library for inter-domain communication. A standard Xen ring
- * buffer is used, with a datagram-based interface built on top. The grant
- * reference and event channels are shared in XenStore under a user-specified
- * path.
- *
- * The ring.h macros define an asymmetric interface to a shared data structure
- * that assumes all rings reside in a single contiguous memory space. This is
- * not suitable for vchan because the interface to the ring is symmetric except
- * for the setup. Unlike the producer-consumer rings defined in ring.h, the
- * size of the rings used in vchan are determined at execution time instead of
- * compile time, so the macros in ring.h cannot be used to access the rings.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-struct ring_shared {
- uint32_t cons, prod;
-};
-
-#define VCHAN_NOTIFY_WRITE 0x1
-#define VCHAN_NOTIFY_READ 0x2
-
-/**
- * vchan_interface: primary shared data structure
- */
-struct vchan_interface {
- /**
- * Standard consumer/producer interface, one pair per buffer
- * left is client write, server read
- * right is client read, server write
- */
- struct ring_shared left, right;
- /**
- * size of the rings, which determines their location
- * 10 - at offset 1024 in ring's page
- * 11 - at offset 2048 in ring's page
- * 12+ - uses 2^(N-12) grants to describe the multi-page ring
- * These should remain constant once the page is shared.
- * Only one of the two orders can be 10 (or 11).
- */
- uint16_t left_order, right_order;
- /**
- * Shutdown detection:
- * 0: client (or server) has exited
- * 1: client (or server) is connected
- * 2: client has not yet connected
- */
- uint8_t cli_live, srv_live;
- /**
- * Notification bits:
- * VCHAN_NOTIFY_WRITE: send notify when data is written
- * VCHAN_NOTIFY_READ: send notify when data is read (consumed)
- * cli_notify is used for the client to inform the server of its action
- */
- uint8_t cli_notify, srv_notify;
- /**
- * Grant list: ordering is left, right. Must not extend into actual ring
- * or grow beyond the end of the initial shared page.
- * These should remain constant once the page is shared, to allow
- * for possible remapping by a client that restarts.
- */
- uint32_t grants[0];
-};
-
+++ /dev/null
-/******************************************************************************
- * netif.h
- *
- * Unified network-device I/O interface for Xen guest OSes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2003-2004, Keir Fraser
- */
-
-#ifndef __XEN_PUBLIC_IO_NETIF_H__
-#define __XEN_PUBLIC_IO_NETIF_H__
-
-#include "ring.h"
-#include "../grant_table.h"
-
-/*
- * Older implementation of Xen network frontend / backend has an
- * implicit dependency on the MAX_SKB_FRAGS as the maximum number of
- * ring slots a skb can use. Netfront / netback may not work as
- * expected when frontend and backend have different MAX_SKB_FRAGS.
- *
- * A better approach is to add mechanism for netfront / netback to
- * negotiate this value. However we cannot fix all possible
- * frontends, so we need to define a value which states the minimum
- * slots backend must support.
- *
- * The minimum value derives from older Linux kernel's MAX_SKB_FRAGS
- * (18), which is proved to work with most frontends. Any new backend
- * which doesn't negotiate with frontend should expect frontend to
- * send a valid packet using slots up to this value.
- */
-#define XEN_NETIF_NR_SLOTS_MIN 18
-
-/*
- * Notifications after enqueuing any type of message should be conditional on
- * the appropriate req_event or rsp_event field in the shared ring.
- * If the client sends notification for rx requests then it should specify
- * feature 'feature-rx-notify' via xenbus. Otherwise the backend will assume
- * that it cannot safely queue packets (as it may not be kicked to send them).
- */
-
-/*
- * "feature-split-event-channels" is introduced to separate guest TX
- * and RX notification. Backend either doesn't support this feature or
- * advertises it via xenstore as 0 (disabled) or 1 (enabled).
- *
- * To make use of this feature, frontend should allocate two event
- * channels for TX and RX, advertise them to backend as
- * "event-channel-tx" and "event-channel-rx" respectively. If frontend
- * doesn't want to use this feature, it just writes "event-channel"
- * node as before.
- */
-
-/*
- * Multiple transmit and receive queues:
- * If supported, the backend will write the key "multi-queue-max-queues" to
- * the directory for that vif, and set its value to the maximum supported
- * number of queues.
- * Frontends that are aware of this feature and wish to use it can write the
- * key "multi-queue-num-queues", set to the number they wish to use, which
- * must be greater than zero, and no more than the value reported by the backend
- * in "multi-queue-max-queues".
- *
- * Queues replicate the shared rings and event channels.
- * "feature-split-event-channels" may optionally be used when using
- * multiple queues, but is not mandatory.
- *
- * Each queue consists of one shared ring pair, i.e. there must be the same
- * number of tx and rx rings.
- *
- * For frontends requesting just one queue, the usual event-channel and
- * ring-ref keys are written as before, simplifying the backend processing
- * to avoid distinguishing between a frontend that doesn't understand the
- * multi-queue feature, and one that does, but requested only one queue.
- *
- * Frontends requesting two or more queues must not write the toplevel
- * event-channel (or event-channel-{tx,rx}) and {tx,rx}-ring-ref keys,
- * instead writing those keys under sub-keys having the name "queue-N" where
- * N is the integer ID of the queue for which those keys belong. Queues
- * are indexed from zero. For example, a frontend with two queues and split
- * event channels must write the following set of queue-related keys:
- *
- * /local/domain/1/device/vif/0/multi-queue-num-queues = "2"
- * /local/domain/1/device/vif/0/queue-0 = ""
- * /local/domain/1/device/vif/0/queue-0/tx-ring-ref = "<ring-ref-tx0>"
- * /local/domain/1/device/vif/0/queue-0/rx-ring-ref = "<ring-ref-rx0>"
- * /local/domain/1/device/vif/0/queue-0/event-channel-tx = "<evtchn-tx0>"
- * /local/domain/1/device/vif/0/queue-0/event-channel-rx = "<evtchn-rx0>"
- * /local/domain/1/device/vif/0/queue-1 = ""
- * /local/domain/1/device/vif/0/queue-1/tx-ring-ref = "<ring-ref-tx1>"
- * /local/domain/1/device/vif/0/queue-1/rx-ring-ref = "<ring-ref-rx1"
- * /local/domain/1/device/vif/0/queue-1/event-channel-tx = "<evtchn-tx1>"
- * /local/domain/1/device/vif/0/queue-1/event-channel-rx = "<evtchn-rx1>"
- *
- * If there is any inconsistency in the XenStore data, the backend may
- * choose not to connect any queues, instead treating the request as an
- * error. This includes scenarios where more (or fewer) queues were
- * requested than the frontend provided details for.
- *
- * Mapping of packets to queues is considered to be a function of the
- * transmitting system (backend or frontend) and is not negotiated
- * between the two. Guests are free to transmit packets on any queue
- * they choose, provided it has been set up correctly. Guests must be
- * prepared to receive packets on any queue they have requested be set up.
- */
-
-/*
- * "feature-no-csum-offload" should be used to turn IPv4 TCP/UDP checksum
- * offload off or on. If it is missing then the feature is assumed to be on.
- * "feature-ipv6-csum-offload" should be used to turn IPv6 TCP/UDP checksum
- * offload on or off. If it is missing then the feature is assumed to be off.
- */
-
-/*
- * "feature-gso-tcpv4" and "feature-gso-tcpv6" advertise the capability to
- * handle large TCP packets (in IPv4 or IPv6 form respectively). Neither
- * frontends nor backends are assumed to be capable unless the flags are
- * present.
- */
-
-/*
- * This is the 'wire' format for packets:
- * Request 1: netif_tx_request -- NETTXF_* (any flags)
- * [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info)
- * [Request 3: netif_tx_extra] (only if request 2 has XEN_NETIF_EXTRA_MORE)
- * Request 4: netif_tx_request -- NETTXF_more_data
- * Request 5: netif_tx_request -- NETTXF_more_data
- * ...
- * Request N: netif_tx_request -- 0
- */
-
-/* Protocol checksum field is blank in the packet (hardware offload)? */
-#define _NETTXF_csum_blank (0)
-#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
-
-/* Packet data has been validated against protocol checksum. */
-#define _NETTXF_data_validated (1)
-#define NETTXF_data_validated (1U<<_NETTXF_data_validated)
-
-/* Packet continues in the next request descriptor. */
-#define _NETTXF_more_data (2)
-#define NETTXF_more_data (1U<<_NETTXF_more_data)
-
-/* Packet to be followed by extra descriptor(s). */
-#define _NETTXF_extra_info (3)
-#define NETTXF_extra_info (1U<<_NETTXF_extra_info)
-
-#define XEN_NETIF_MAX_TX_SIZE 0xFFFF
-struct netif_tx_request {
- grant_ref_t gref; /* Reference to buffer page */
- uint16_t offset; /* Offset within buffer page */
- uint16_t flags; /* NETTXF_* */
- uint16_t id; /* Echoed in response message. */
- uint16_t size; /* Packet size in bytes. */
-};
-typedef struct netif_tx_request netif_tx_request_t;
-
-/* Types of netif_extra_info descriptors. */
-#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */
-#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */
-#define XEN_NETIF_EXTRA_TYPE_MCAST_ADD (2) /* u.mcast */
-#define XEN_NETIF_EXTRA_TYPE_MCAST_DEL (3) /* u.mcast */
-#define XEN_NETIF_EXTRA_TYPE_MAX (4)
-
-/* netif_extra_info flags. */
-#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
-#define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
-
-/* GSO types */
-#define XEN_NETIF_GSO_TYPE_NONE (0)
-#define XEN_NETIF_GSO_TYPE_TCPV4 (1)
-#define XEN_NETIF_GSO_TYPE_TCPV6 (2)
-
-/*
- * This structure needs to fit within both netif_tx_request and
- * netif_rx_response for compatibility.
- */
-struct netif_extra_info {
- uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */
- uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
-
- union {
- /*
- * XEN_NETIF_EXTRA_TYPE_GSO:
- */
- struct {
- /*
- * Maximum payload size of each segment. For example, for TCP this
- * is just the path MSS.
- */
- uint16_t size;
-
- /*
- * GSO type. This determines the protocol of the packet and any
- * extra features required to segment the packet properly.
- */
- uint8_t type; /* XEN_NETIF_GSO_TYPE_* */
-
- /* Future expansion. */
- uint8_t pad;
-
- /*
- * GSO features. This specifies any extra GSO features required
- * to process this packet, such as ECN support for TCPv4.
- */
- uint16_t features; /* XEN_NETIF_GSO_FEAT_* */
- } gso;
-
- /*
- * XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}:
- * Backend advertises availability via 'feature-multicast-control'
- * xenbus node containing value '1'.
- * Frontend requests this feature by advertising
- * 'request-multicast-control' xenbus node containing value '1'.
- * If multicast control is requested then multicast flooding is
- * disabled and the frontend must explicitly register its interest
- * in multicast groups using dummy transmit requests containing
- * MCAST_{ADD,DEL} extra-info fragments.
- */
- struct {
- uint8_t addr[6]; /* Address to add/remove. */
- } mcast;
-
- uint16_t pad[3];
- } u;
-};
-typedef struct netif_extra_info netif_extra_info_t;
-
-struct netif_tx_response {
- uint16_t id;
- int16_t status; /* NETIF_RSP_* */
-};
-typedef struct netif_tx_response netif_tx_response_t;
-
-struct netif_rx_request {
- uint16_t id; /* Echoed in response message. */
- grant_ref_t gref; /* Reference to incoming granted frame */
-};
-typedef struct netif_rx_request netif_rx_request_t;
-
-/* Packet data has been validated against protocol checksum. */
-#define _NETRXF_data_validated (0)
-#define NETRXF_data_validated (1U<<_NETRXF_data_validated)
-
-/* Protocol checksum field is blank in the packet (hardware offload)? */
-#define _NETRXF_csum_blank (1)
-#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank)
-
-/* Packet continues in the next request descriptor. */
-#define _NETRXF_more_data (2)
-#define NETRXF_more_data (1U<<_NETRXF_more_data)
-
-/* Packet to be followed by extra descriptor(s). */
-#define _NETRXF_extra_info (3)
-#define NETRXF_extra_info (1U<<_NETRXF_extra_info)
-
-struct netif_rx_response {
- uint16_t id;
- uint16_t offset; /* Offset in page of start of received packet */
- uint16_t flags; /* NETRXF_* */
- int16_t status; /* -ve: NETIF_RSP_* ; +ve: Rx'ed pkt size. */
-};
-typedef struct netif_rx_response netif_rx_response_t;
-
-/*
- * Generate netif ring structures and types.
- */
-
-DEFINE_RING_TYPES(netif_tx, struct netif_tx_request, struct netif_tx_response);
-DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);
-
-#define NETIF_RSP_DROPPED -2
-#define NETIF_RSP_ERROR -1
-#define NETIF_RSP_OKAY 0
-/* No response: used for auxiliary requests (e.g., netif_tx_extra). */
-#define NETIF_RSP_NULL 1
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * PCI Backend/Frontend Common Data Structures & Macros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
- */
-#ifndef __XEN_PCI_COMMON_H__
-#define __XEN_PCI_COMMON_H__
-
-/* Be sure to bump this number if you change this file */
-#define XEN_PCI_MAGIC "7"
-
-/* xen_pci_sharedinfo flags */
-#define _XEN_PCIF_active (0)
-#define XEN_PCIF_active (1<<_XEN_PCIF_active)
-#define _XEN_PCIB_AERHANDLER (1)
-#define XEN_PCIB_AERHANDLER (1<<_XEN_PCIB_AERHANDLER)
-#define _XEN_PCIB_active (2)
-#define XEN_PCIB_active (1<<_XEN_PCIB_active)
-
-/* xen_pci_op commands */
-#define XEN_PCI_OP_conf_read (0)
-#define XEN_PCI_OP_conf_write (1)
-#define XEN_PCI_OP_enable_msi (2)
-#define XEN_PCI_OP_disable_msi (3)
-#define XEN_PCI_OP_enable_msix (4)
-#define XEN_PCI_OP_disable_msix (5)
-#define XEN_PCI_OP_aer_detected (6)
-#define XEN_PCI_OP_aer_resume (7)
-#define XEN_PCI_OP_aer_mmio (8)
-#define XEN_PCI_OP_aer_slotreset (9)
-#define XEN_PCI_OP_enable_multi_msi (10)
-
-/* xen_pci_op error numbers */
-#define XEN_PCI_ERR_success (0)
-#define XEN_PCI_ERR_dev_not_found (-1)
-#define XEN_PCI_ERR_invalid_offset (-2)
-#define XEN_PCI_ERR_access_denied (-3)
-#define XEN_PCI_ERR_not_implemented (-4)
-/* XEN_PCI_ERR_op_failed - backend failed to complete the operation */
-#define XEN_PCI_ERR_op_failed (-5)
-
-/*
- * it should be PAGE_SIZE-sizeof(struct xen_pci_op))/sizeof(struct msix_entry))
- * Should not exceed 128
- */
-#define SH_INFO_MAX_VEC 128
-
-struct xen_msix_entry {
- uint16_t vector;
- uint16_t entry;
-};
-struct xen_pci_op {
- /* IN: what action to perform: XEN_PCI_OP_* */
- uint32_t cmd;
-
- /* OUT: will contain an error number (if any) from errno.h */
- int32_t err;
-
- /* IN: which device to touch */
- uint32_t domain; /* PCI Domain/Segment */
- uint32_t bus;
- uint32_t devfn;
-
- /* IN: which configuration registers to touch */
- int32_t offset;
- int32_t size;
-
- /* IN/OUT: Contains the result after a READ or the value to WRITE */
- uint32_t value;
- /* IN: Contains extra infor for this operation */
- uint32_t info;
- /*IN: param for msi-x */
- struct xen_msix_entry msix_entries[SH_INFO_MAX_VEC];
-};
-
-/*used for pcie aer handling*/
-struct xen_pcie_aer_op
-{
-
- /* IN: what action to perform: XEN_PCI_OP_* */
- uint32_t cmd;
- /*IN/OUT: return aer_op result or carry error_detected state as input*/
- int32_t err;
-
- /* IN: which device to touch */
- uint32_t domain; /* PCI Domain/Segment*/
- uint32_t bus;
- uint32_t devfn;
-};
-struct xen_pci_sharedinfo {
- /* flags - XEN_PCIF_* */
- uint32_t flags;
- struct xen_pci_op op;
- struct xen_pcie_aer_op aer_op;
-};
-
-#endif /* __XEN_PCI_COMMON_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * protocols.h
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PROTOCOLS_H__
-#define __XEN_PROTOCOLS_H__
-
-#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi"
-#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
-#define XEN_IO_PROTO_ABI_ARM "arm-abi"
-
-#if defined(__i386__)
-# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
-#elif defined(__x86_64__)
-# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
-#elif defined(__arm__) || defined(__aarch64__)
-# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
-#else
-# error arch fixup needed here
-#endif
-
-#endif
+++ /dev/null
-/******************************************************************************
- * ring.h
- *
- * Shared producer-consumer ring macros.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Tim Deegan and Andrew Warfield November 2004.
- */
-
-#ifndef __XEN_PUBLIC_IO_RING_H__
-#define __XEN_PUBLIC_IO_RING_H__
-
-#include "../xen-compat.h"
-
-#if __XEN_INTERFACE_VERSION__ < 0x00030208
-#define xen_mb() mb()
-#define xen_rmb() rmb()
-#define xen_wmb() wmb()
-#endif
-
-typedef unsigned int RING_IDX;
-
-/* Round a 32-bit unsigned constant down to the nearest power of two. */
-#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
-#define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
-#define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
-#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
-#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
-
-/*
- * Calculate size of a shared ring, given the total available space for the
- * ring and indexes (_sz), and the name tag of the request/response structure.
- * A ring contains as many entries as will fit, rounded down to the nearest
- * power of two (so we can mask with (size-1) to loop around).
- */
-#define __CONST_RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
- sizeof(((struct _s##_sring *)0)->ring[0])))
-/*
- * The same for passing in an actual pointer instead of a name tag.
- */
-#define __RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
-
-/*
- * Macros to make the correct C datatypes for a new kind of ring.
- *
- * To make a new ring datatype, you need to have two message structures,
- * let's say request_t, and response_t already defined.
- *
- * In a header where you want the ring datatype declared, you then do:
- *
- * DEFINE_RING_TYPES(mytag, request_t, response_t);
- *
- * These expand out to give you a set of types, as you can see below.
- * The most important of these are:
- *
- * mytag_sring_t - The shared ring.
- * mytag_front_ring_t - The 'front' half of the ring.
- * mytag_back_ring_t - The 'back' half of the ring.
- *
- * To initialize a ring in your code you need to know the location and size
- * of the shared memory area (PAGE_SIZE, for instance). To initialise
- * the front half:
- *
- * mytag_front_ring_t front_ring;
- * SHARED_RING_INIT((mytag_sring_t *)shared_page);
- * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
- *
- * Initializing the back follows similarly (note that only the front
- * initializes the shared ring):
- *
- * mytag_back_ring_t back_ring;
- * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
- */
-
-#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
- \
-/* Shared ring entry */ \
-union __name##_sring_entry { \
- __req_t req; \
- __rsp_t rsp; \
-}; \
- \
-/* Shared ring page */ \
-struct __name##_sring { \
- RING_IDX req_prod, req_event; \
- RING_IDX rsp_prod, rsp_event; \
- union { \
- struct { \
- uint8_t smartpoll_active; \
- } netif; \
- struct { \
- uint8_t msg; \
- } tapif_user; \
- uint8_t pvt_pad[4]; \
- } private; \
- uint8_t __pad[44]; \
- union __name##_sring_entry ring[1]; /* variable-length */ \
-}; \
- \
-/* "Front" end's private variables */ \
-struct __name##_front_ring { \
- RING_IDX req_prod_pvt; \
- RING_IDX rsp_cons; \
- unsigned int nr_ents; \
- struct __name##_sring *sring; \
-}; \
- \
-/* "Back" end's private variables */ \
-struct __name##_back_ring { \
- RING_IDX rsp_prod_pvt; \
- RING_IDX req_cons; \
- unsigned int nr_ents; \
- struct __name##_sring *sring; \
-}; \
- \
-/* Syntactic sugar */ \
-typedef struct __name##_sring __name##_sring_t; \
-typedef struct __name##_front_ring __name##_front_ring_t; \
-typedef struct __name##_back_ring __name##_back_ring_t
-
-/*
- * Macros for manipulating rings.
- *
- * FRONT_RING_whatever works on the "front end" of a ring: here
- * requests are pushed on to the ring and responses taken off it.
- *
- * BACK_RING_whatever works on the "back end" of a ring: here
- * requests are taken off the ring and responses put on.
- *
- * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
- * This is OK in 1-for-1 request-response situations where the
- * requestor (front end) never has more than RING_SIZE()-1
- * outstanding requests.
- */
-
-/* Initialising empty rings */
-#define SHARED_RING_INIT(_s) do { \
- (_s)->req_prod = (_s)->rsp_prod = 0; \
- (_s)->req_event = (_s)->rsp_event = 1; \
- (void)memset((_s)->private.pvt_pad, 0, sizeof((_s)->private.pvt_pad)); \
- (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
-} while(0)
-
-#define FRONT_RING_INIT(_r, _s, __size) do { \
- (_r)->req_prod_pvt = 0; \
- (_r)->rsp_cons = 0; \
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
- (_r)->sring = (_s); \
-} while (0)
-
-#define BACK_RING_INIT(_r, _s, __size) do { \
- (_r)->rsp_prod_pvt = 0; \
- (_r)->req_cons = 0; \
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
- (_r)->sring = (_s); \
-} while (0)
-
-/* How big is this ring? */
-#define RING_SIZE(_r) \
- ((_r)->nr_ents)
-
-/* Number of free requests (for use on front side only). */
-#define RING_FREE_REQUESTS(_r) \
- (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
-
-/* Test if there is an empty slot available on the front ring.
- * (This is only meaningful from the front. )
- */
-#define RING_FULL(_r) \
- (RING_FREE_REQUESTS(_r) == 0)
-
-/* Test if there are outstanding messages to be processed on a ring. */
-#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
- ((_r)->sring->rsp_prod - (_r)->rsp_cons)
-
-#ifdef __GNUC__
-#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
- unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
- unsigned int rsp = RING_SIZE(_r) - \
- ((_r)->req_cons - (_r)->rsp_prod_pvt); \
- req < rsp ? req : rsp; \
-})
-#else
-/* Same as above, but without the nice GCC ({ ... }) syntax. */
-#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
- ((((_r)->sring->req_prod - (_r)->req_cons) < \
- (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
- ((_r)->sring->req_prod - (_r)->req_cons) : \
- (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
-#endif
-
-/* Direct access to individual ring elements, by index. */
-#define RING_GET_REQUEST(_r, _idx) \
- (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
-
-#define RING_GET_RESPONSE(_r, _idx) \
- (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
-
-/* Loop termination condition: Would the specified index overflow the ring? */
-#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
- (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
-
-/* Ill-behaved frontend determination: Can there be this many requests? */
-#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \
- (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
-
-#define RING_PUSH_REQUESTS(_r) do { \
- xen_wmb(); /* back sees requests /before/ updated producer index */ \
- (_r)->sring->req_prod = (_r)->req_prod_pvt; \
-} while (0)
-
-#define RING_PUSH_RESPONSES(_r) do { \
- xen_wmb(); /* front sees resps /before/ updated producer index */ \
- (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
-} while (0)
-
-/*
- * Notification hold-off (req_event and rsp_event):
- *
- * When queueing requests or responses on a shared ring, it may not always be
- * necessary to notify the remote end. For example, if requests are in flight
- * in a backend, the front may be able to queue further requests without
- * notifying the back (if the back checks for new requests when it queues
- * responses).
- *
- * When enqueuing requests or responses:
- *
- * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
- * is a boolean return value. True indicates that the receiver requires an
- * asynchronous notification.
- *
- * After dequeuing requests or responses (before sleeping the connection):
- *
- * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
- * The second argument is a boolean return value. True indicates that there
- * are pending messages on the ring (i.e., the connection should not be put
- * to sleep).
- *
- * These macros will set the req_event/rsp_event field to trigger a
- * notification on the very next message that is enqueued. If you want to
- * create batches of work (i.e., only receive a notification after several
- * messages have been enqueued) then you will need to create a customised
- * version of the FINAL_CHECK macro in your own code, which sets the event
- * field appropriately.
- */
-
-#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
- RING_IDX __old = (_r)->sring->req_prod; \
- RING_IDX __new = (_r)->req_prod_pvt; \
- xen_wmb(); /* back sees requests /before/ updated producer index */ \
- (_r)->sring->req_prod = __new; \
- xen_mb(); /* back sees new requests /before/ we check req_event */ \
- (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
- (RING_IDX)(__new - __old)); \
-} while (0)
-
-#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
- RING_IDX __old = (_r)->sring->rsp_prod; \
- RING_IDX __new = (_r)->rsp_prod_pvt; \
- xen_wmb(); /* front sees resps /before/ updated producer index */ \
- (_r)->sring->rsp_prod = __new; \
- xen_mb(); /* front sees new resps /before/ we check rsp_event */ \
- (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
- (RING_IDX)(__new - __old)); \
-} while (0)
-
-#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
- if (_work_to_do) break; \
- (_r)->sring->req_event = (_r)->req_cons + 1; \
- xen_mb(); \
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
-} while (0)
-
-#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
- if (_work_to_do) break; \
- (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
- xen_mb(); \
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
-} while (0)
-
-#endif /* __XEN_PUBLIC_IO_RING_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * tpmif.h
- *
- * TPM I/O interface for Xen guest OSes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * Author: Stefan Berger, stefanb@us.ibm.com
- * Grant table support: Mahadevan Gomathisankaran
- *
- * This code has been derived from tools/libxc/xen/io/netif.h
- *
- * Copyright (c) 2003-2004, Keir Fraser
- */
-
-#ifndef __XEN_PUBLIC_IO_TPMIF_H__
-#define __XEN_PUBLIC_IO_TPMIF_H__
-
-#include "../grant_table.h"
-
-struct tpmif_tx_request {
- unsigned long addr; /* Machine address of packet. */
- grant_ref_t ref; /* grant table access reference */
- uint16_t unused;
- uint16_t size; /* Packet size in bytes. */
-};
-typedef struct tpmif_tx_request tpmif_tx_request_t;
-
-/*
- * The TPMIF_TX_RING_SIZE defines the number of pages the
- * front-end and backend can exchange (= size of array).
- */
-typedef uint32_t TPMIF_RING_IDX;
-
-#define TPMIF_TX_RING_SIZE 1
-
-/* This structure must fit in a memory page. */
-
-struct tpmif_ring {
- struct tpmif_tx_request req;
-};
-typedef struct tpmif_ring tpmif_ring_t;
-
-struct tpmif_tx_interface {
- struct tpmif_ring ring[TPMIF_TX_RING_SIZE];
-};
-typedef struct tpmif_tx_interface tpmif_tx_interface_t;
-
-/******************************************************************************
- * TPM I/O interface for Xen guest OSes, v2
- *
- * Author: Daniel De Graaf <dgdegra@tycho.nsa.gov>
- *
- * This protocol emulates the request/response behavior of a TPM using a Xen
- * shared memory interface. All interaction with the TPM is at the direction
- * of the frontend, since a TPM (hardware or virtual) is a passive device -
- * the backend only processes commands as requested by the frontend.
- *
- * The frontend sends a request to the TPM by populating the shared page with
- * the request packet, changing the state to TPMIF_STATE_SUBMIT, and sending
- * and event channel notification. When the backend is finished, it will set
- * the state to TPMIF_STATE_FINISH and send an event channel notification.
- *
- * In order to allow long-running commands to be canceled, the frontend can
- * at any time change the state to TPMIF_STATE_CANCEL and send a notification.
- * The TPM can either finish the command (changing state to TPMIF_STATE_FINISH)
- * or can cancel the command and change the state to TPMIF_STATE_IDLE. The TPM
- * can also change the state to TPMIF_STATE_IDLE instead of TPMIF_STATE_FINISH
- * if another reason for cancellation is required - for example, a physical
- * TPM may cancel a command if the interface is seized by another locality.
- *
- * The TPM command format is defined by the TCG, and is available at
- * http://www.trustedcomputinggroup.org/resources/tpm_main_specification
- */
-
-enum tpmif_state {
- TPMIF_STATE_IDLE, /* no contents / vTPM idle / cancel complete */
- TPMIF_STATE_SUBMIT, /* request ready / vTPM working */
- TPMIF_STATE_FINISH, /* response ready / vTPM idle */
- TPMIF_STATE_CANCEL, /* cancel requested / vTPM working */
-};
-/* Note: The backend should only change state to IDLE or FINISH, while the
- * frontend should only change to SUBMIT or CANCEL. Status changes do not need
- * to use atomic operations.
- */
-
-
-/* The shared page for vTPM request/response packets looks like:
- *
- * Offset Contents
- * =================================================
- * 0 struct tpmif_shared_page
- * 16 [optional] List of grant IDs
- * 16+4*nr_extra_pages TPM packet data
- *
- * If the TPM packet data extends beyond the end of a single page, the grant IDs
- * defined in extra_pages are used as if they were mapped immediately following
- * the primary shared page. The grants are allocated by the frontend and mapped
- * by the backend. Before sending a request spanning multiple pages, the
- * frontend should verify that the TPM supports such large requests by querying
- * the TPM_CAP_PROP_INPUT_BUFFER property from the TPM.
- */
-struct tpmif_shared_page {
- uint32_t length; /* request/response length in bytes */
-
- uint8_t state; /* enum tpmif_state */
- uint8_t locality; /* for the current request */
- uint8_t pad; /* should be zero */
-
- uint8_t nr_extra_pages; /* extra pages for long packets; may be zero */
- uint32_t extra_pages[0]; /* grant IDs; length is actually nr_extra_pages */
-};
-typedef struct tpmif_shared_page tpmif_shared_page_t;
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * usbif.h
- *
- * USB I/O interface for Xen guest OSes.
- *
- * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
- * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_IO_USBIF_H__
-#define __XEN_PUBLIC_IO_USBIF_H__
-
-#include "ring.h"
-#include "../grant_table.h"
-
-enum usb_spec_version {
- USB_VER_UNKNOWN = 0,
- USB_VER_USB11,
- USB_VER_USB20,
- USB_VER_USB30, /* not supported yet */
-};
-
-/*
- * USB pipe in usbif_request
- *
- * bits 0-5 are specific bits for virtual USB driver.
- * bits 7-31 are standard urb pipe.
- *
- * - port number(NEW): bits 0-4
- * (USB_MAXCHILDREN is 31)
- *
- * - operation flag(NEW): bit 5
- * (0 = submit urb,
- * 1 = unlink urb)
- *
- * - direction: bit 7
- * (0 = Host-to-Device [Out]
- * 1 = Device-to-Host [In])
- *
- * - device address: bits 8-14
- *
- * - endpoint: bits 15-18
- *
- * - pipe type: bits 30-31
- * (00 = isochronous, 01 = interrupt,
- * 10 = control, 11 = bulk)
- */
-#define usbif_pipeportnum(pipe) ((pipe) & 0x1f)
-#define usbif_setportnum_pipe(pipe, portnum) \
- ((pipe)|(portnum))
-
-#define usbif_pipeunlink(pipe) ((pipe) & 0x20)
-#define usbif_pipesubmit(pipe) (!usbif_pipeunlink(pipe))
-#define usbif_setunlink_pipe(pipe) ((pipe)|(0x20))
-
-#define USBIF_MAX_SEGMENTS_PER_REQUEST (16)
-
-/*
- * RING for transferring urbs.
- */
-struct usbif_request_segment {
- grant_ref_t gref;
- uint16_t offset;
- uint16_t length;
-};
-
-struct usbif_urb_request {
- uint16_t id; /* request id */
- uint16_t nr_buffer_segs; /* number of urb->transfer_buffer segments */
-
- /* basic urb parameter */
- uint32_t pipe;
- uint16_t transfer_flags;
- uint16_t buffer_length;
- union {
- uint8_t ctrl[8]; /* setup_packet (Ctrl) */
-
- struct {
- uint16_t interval; /* maximum (1024*8) in usb core */
- uint16_t start_frame; /* start frame */
- uint16_t number_of_packets; /* number of ISO packet */
- uint16_t nr_frame_desc_segs; /* number of iso_frame_desc segments */
- } isoc;
-
- struct {
- uint16_t interval; /* maximum (1024*8) in usb core */
- uint16_t pad[3];
- } intr;
-
- struct {
- uint16_t unlink_id; /* unlink request id */
- uint16_t pad[3];
- } unlink;
-
- } u;
-
- /* urb data segments */
- struct usbif_request_segment seg[USBIF_MAX_SEGMENTS_PER_REQUEST];
-};
-typedef struct usbif_urb_request usbif_urb_request_t;
-
-struct usbif_urb_response {
- uint16_t id; /* request id */
- uint16_t start_frame; /* start frame (ISO) */
- int32_t status; /* status (non-ISO) */
- int32_t actual_length; /* actual transfer length */
- int32_t error_count; /* number of ISO errors */
-};
-typedef struct usbif_urb_response usbif_urb_response_t;
-
-DEFINE_RING_TYPES(usbif_urb, struct usbif_urb_request, struct usbif_urb_response);
-#define USB_URB_RING_SIZE __CONST_RING_SIZE(usbif_urb, PAGE_SIZE)
-
-/*
- * RING for notifying connect/disconnect events to frontend
- */
-struct usbif_conn_request {
- uint16_t id;
-};
-typedef struct usbif_conn_request usbif_conn_request_t;
-
-struct usbif_conn_response {
- uint16_t id; /* request id */
- uint8_t portnum; /* port number */
- uint8_t speed; /* usb_device_speed */
-};
-typedef struct usbif_conn_response usbif_conn_response_t;
-
-DEFINE_RING_TYPES(usbif_conn, struct usbif_conn_request, struct usbif_conn_response);
-#define USB_CONN_RING_SIZE __CONST_RING_SIZE(usbif_conn, PAGE_SIZE)
-
-#endif /* __XEN_PUBLIC_IO_USBIF_H__ */
+++ /dev/null
-/******************************************************************************
- * vscsiif.h
- *
- * Based on the blkif.h code.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright(c) FUJITSU Limited 2008.
- */
-
-#ifndef __XEN__PUBLIC_IO_SCSI_H__
-#define __XEN__PUBLIC_IO_SCSI_H__
-
-#include "ring.h"
-#include "../grant_table.h"
-
-/*
- * Feature and Parameter Negotiation
- * =================================
- * The two halves of a Xen pvSCSI driver utilize nodes within the XenStore to
- * communicate capabilities and to negotiate operating parameters. This
- * section enumerates these nodes which reside in the respective front and
- * backend portions of the XenStore, following the XenBus convention.
- *
- * Any specified default value is in effect if the corresponding XenBus node
- * is not present in the XenStore.
- *
- * XenStore nodes in sections marked "PRIVATE" are solely for use by the
- * driver side whose XenBus tree contains them.
- *
- *****************************************************************************
- * Backend XenBus Nodes
- *****************************************************************************
- *
- *------------------ Backend Device Identification (PRIVATE) ------------------
- *
- * p-devname
- * Values: string
- *
- * A free string used to identify the physical device (e.g. a disk name).
- *
- * p-dev
- * Values: string
- *
- * A string specifying the backend device: either a 4-tuple "h:c:t:l"
- * (host, controller, target, lun, all integers), or a WWN (e.g.
- * "naa.60014054ac780582").
- *
- * v-dev
- * Values: string
- *
- * A string specifying the frontend device in form of a 4-tuple "h:c:t:l"
- * (host, controller, target, lun, all integers).
- *
- *--------------------------------- Features ---------------------------------
- *
- * feature-sg-grant
- * Values: unsigned [VSCSIIF_SG_TABLESIZE...65535]
- * Default Value: 0
- *
- * Specifies the maximum number of scatter/gather elements in grant pages
- * supported. If not set, the backend supports up to VSCSIIF_SG_TABLESIZE
- * SG elements specified directly in the request.
- *
- *****************************************************************************
- * Frontend XenBus Nodes
- *****************************************************************************
- *
- *----------------------- Request Transport Parameters -----------------------
- *
- * event-channel
- * Values: unsigned
- *
- * The identifier of the Xen event channel used to signal activity
- * in the ring buffer.
- *
- * ring-ref
- * Values: unsigned
- *
- * The Xen grant reference granting permission for the backend to map
- * the sole page in a single page sized ring buffer.
- *
- * protocol
- * Values: string (XEN_IO_PROTO_ABI_*)
- * Default Value: XEN_IO_PROTO_ABI_NATIVE
- *
- * The machine ABI rules governing the format of all ring request and
- * response structures.
- */
-
-/* Requests from the frontend to the backend */
-
-/*
- * Request a SCSI operation specified via a CDB in vscsiif_request.cmnd.
- * The target is specified via channel, id and lun.
- *
- * The operation to be performed is specified via a CDB in cmnd[], the length
- * of the CDB is in cmd_len. sc_data_direction specifies the direction of data
- * (to the device, from the device, or none at all).
- *
- * If data is to be transferred to or from the device the buffer(s) in the
- * guest memory is/are specified via one or multiple scsiif_request_segment
- * descriptors each specifying a memory page via a grant_ref_t, a offset into
- * the page and the length of the area in that page. All scsiif_request_segment
- * areas concatenated form the resulting data buffer used by the operation.
- * If the number of scsiif_request_segment areas is not too large (less than
- * or equal VSCSIIF_SG_TABLESIZE) the areas can be specified directly in the
- * seg[] array and the number of valid scsiif_request_segment elements is to be
- * set in nr_segments.
- *
- * If "feature-sg-grant" in the Xenstore is set it is possible to specify more
- * than VSCSIIF_SG_TABLESIZE scsiif_request_segment elements via indirection.
- * The maximum number of allowed scsiif_request_segment elements is the value
- * of the "feature-sg-grant" entry from Xenstore. When using indirection the
- * seg[] array doesn't contain specifications of the data buffers, but
- * references to scsiif_request_segment arrays, which in turn reference the
- * data buffers. While nr_segments holds the number of populated seg[] entries
- * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment
- * elements referencing the target data buffers is calculated from the lengths
- * of the seg[] elements (the sum of all valid seg[].length divided by the
- * size of one scsiif_request_segment structure). The frontend may use a mix of
- * direct and indirect requests.
- */
-#define VSCSIIF_ACT_SCSI_CDB 1
-
-/*
- * Request abort of a running operation for the specified target given by
- * channel, id, lun and the operation's rqid in ref_rqid.
- */
-#define VSCSIIF_ACT_SCSI_ABORT 2
-
-/*
- * Request a device reset of the specified target (channel and id).
- */
-#define VSCSIIF_ACT_SCSI_RESET 3
-
-/*
- * Preset scatter/gather elements for a following request. Deprecated.
- * Keeping the define only to avoid usage of the value "4" for other actions.
- */
-#define VSCSIIF_ACT_SCSI_SG_PRESET 4
-
-/*
- * Maximum scatter/gather segments per request.
- *
- * Considering balance between allocating at least 16 "vscsiif_request"
- * structures on one page (4096 bytes) and the number of scatter/gather
- * elements needed, we decided to use 26 as a magic number.
- *
- * If "feature-sg-grant" is set, more scatter/gather elements can be specified
- * by placing them in one or more (up to VSCSIIF_SG_TABLESIZE) granted pages.
- * In this case the vscsiif_request seg elements don't contain references to
- * the user data, but to the SG elements referencing the user data.
- */
-#define VSCSIIF_SG_TABLESIZE 26
-
-/*
- * based on Linux kernel 2.6.18, still valid
- *
- * Changing these values requires support of multiple protocols via the rings
- * as "old clients" will blindly use these values and the resulting structure
- * sizes.
- */
-#define VSCSIIF_MAX_COMMAND_SIZE 16
-#define VSCSIIF_SENSE_BUFFERSIZE 96
-
-struct scsiif_request_segment {
- grant_ref_t gref;
- uint16_t offset;
- uint16_t length;
-};
-typedef struct scsiif_request_segment vscsiif_segment_t;
-
-#define VSCSIIF_SG_PER_PAGE (PAGE_SIZE / sizeof(struct scsiif_request_segment))
-
-/* Size of one request is 252 bytes */
-struct vscsiif_request {
- uint16_t rqid; /* private guest value, echoed in resp */
- uint8_t act; /* command between backend and frontend */
- uint8_t cmd_len; /* valid CDB bytes */
-
- uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE]; /* the CDB */
- uint16_t timeout_per_command; /* deprecated: timeout in secs, 0=default */
- uint16_t channel, id, lun; /* (virtual) device specification */
- uint16_t ref_rqid; /* command abort reference */
- uint8_t sc_data_direction; /* for DMA_TO_DEVICE(1)
- DMA_FROM_DEVICE(2)
- DMA_NONE(3) requests */
- uint8_t nr_segments; /* Number of pieces of scatter-gather */
-/*
- * flag in nr_segments: SG elements via grant page
- *
- * If VSCSIIF_SG_GRANT is set, the low 7 bits of nr_segments specify the number
- * of grant pages containing SG elements. Usable if "feature-sg-grant" set.
- */
-#define VSCSIIF_SG_GRANT 0x80
-
- vscsiif_segment_t seg[VSCSIIF_SG_TABLESIZE];
- uint32_t reserved[3];
-};
-typedef struct vscsiif_request vscsiif_request_t;
-
-/*
- * The following interface is deprecated!
- */
-#define VSCSIIF_SG_LIST_SIZE ((sizeof(vscsiif_request_t) - 4) \
- / sizeof(vscsiif_segment_t))
-
-struct vscsiif_sg_list {
- /* First two fields must match struct vscsiif_request! */
- uint16_t rqid; /* private guest value, must match main req */
- uint8_t act; /* VSCSIIF_ACT_SCSI_SG_PRESET */
- uint8_t nr_segments; /* Number of pieces of scatter-gather */
- vscsiif_segment_t seg[VSCSIIF_SG_LIST_SIZE];
-};
-typedef struct vscsiif_sg_list vscsiif_sg_list_t;
-/* End of deprecated interface */
-
-/* Size of one response is 252 bytes */
-struct vscsiif_response {
- uint16_t rqid; /* identifies request */
- uint8_t act; /* deprecated: valid only if SG_PRESET supported */
- uint8_t sense_len;
- uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
- int32_t rslt;
- uint32_t residual_len; /* request bufflen -
- return the value from physical device */
- uint32_t reserved[36];
-};
-typedef struct vscsiif_response vscsiif_response_t;
-
-DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response);
-
-
-#endif /*__XEN__PUBLIC_IO_SCSI_H__*/
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*****************************************************************************
- * xenbus.h
- *
- * Xenbus protocol details.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) 2005 XenSource Ltd.
- */
-
-#ifndef _XEN_PUBLIC_IO_XENBUS_H
-#define _XEN_PUBLIC_IO_XENBUS_H
-
-/*
- * The state of either end of the Xenbus, i.e. the current communication
- * status of initialisation across the bus. States here imply nothing about
- * the state of the connection between the driver and the kernel's device
- * layers.
- */
-enum xenbus_state {
- XenbusStateUnknown = 0,
-
- XenbusStateInitialising = 1,
-
- /*
- * InitWait: Finished early initialisation but waiting for information
- * from the peer or hotplug scripts.
- */
- XenbusStateInitWait = 2,
-
- /*
- * Initialised: Waiting for a connection from the peer.
- */
- XenbusStateInitialised = 3,
-
- XenbusStateConnected = 4,
-
- /*
- * Closing: The device is being closed due to an error or an unplug event.
- */
- XenbusStateClosing = 5,
-
- XenbusStateClosed = 6,
-
- /*
- * Reconfiguring: The device is being reconfigured.
- */
- XenbusStateReconfiguring = 7,
-
- XenbusStateReconfigured = 8
-};
-typedef enum xenbus_state XenbusState;
-
-#endif /* _XEN_PUBLIC_IO_XENBUS_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Details of the "wire" protocol between Xen Store Daemon and client
- * library or guest kernel.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) 2005 Rusty Russell IBM Corporation
- */
-
-#ifndef _XS_WIRE_H
-#define _XS_WIRE_H
-
-enum xsd_sockmsg_type
-{
- XS_DEBUG,
- XS_DIRECTORY,
- XS_READ,
- XS_GET_PERMS,
- XS_WATCH,
- XS_UNWATCH,
- XS_TRANSACTION_START,
- XS_TRANSACTION_END,
- XS_INTRODUCE,
- XS_RELEASE,
- XS_GET_DOMAIN_PATH,
- XS_WRITE,
- XS_MKDIR,
- XS_RM,
- XS_SET_PERMS,
- XS_WATCH_EVENT,
- XS_ERROR,
- XS_IS_DOMAIN_INTRODUCED,
- XS_RESUME,
- XS_SET_TARGET,
- XS_RESTRICT,
- XS_RESET_WATCHES,
-
- XS_INVALID = 0xffff /* Guaranteed to remain an invalid type */
-};
-
-#define XS_WRITE_NONE "NONE"
-#define XS_WRITE_CREATE "CREATE"
-#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
-
-/* We hand errors as strings, for portability. */
-struct xsd_errors
-{
- int errnum;
- const char *errstring;
-};
-#ifdef EINVAL
-#define XSD_ERROR(x) { x, #x }
-/* LINTED: static unused */
-static struct xsd_errors xsd_errors[]
-#if defined(__GNUC__)
-__attribute__((unused))
-#endif
- = {
- XSD_ERROR(EINVAL),
- XSD_ERROR(EACCES),
- XSD_ERROR(EEXIST),
- XSD_ERROR(EISDIR),
- XSD_ERROR(ENOENT),
- XSD_ERROR(ENOMEM),
- XSD_ERROR(ENOSPC),
- XSD_ERROR(EIO),
- XSD_ERROR(ENOTEMPTY),
- XSD_ERROR(ENOSYS),
- XSD_ERROR(EROFS),
- XSD_ERROR(EBUSY),
- XSD_ERROR(EAGAIN),
- XSD_ERROR(EISCONN),
- XSD_ERROR(E2BIG)
-};
-#endif
-
-struct xsd_sockmsg
-{
- uint32_t type; /* XS_??? */
- uint32_t req_id;/* Request identifier, echoed in daemon's response. */
- uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */
- uint32_t len; /* Length of data following this. */
-
- /* Generally followed by nul-terminated string(s). */
-};
-
-enum xs_watch_type
-{
- XS_WATCH_PATH = 0,
- XS_WATCH_TOKEN
-};
-
-/*
- * `incontents 150 xenstore_struct XenStore wire protocol.
- *
- * Inter-domain shared memory communications. */
-#define XENSTORE_RING_SIZE 1024
-typedef uint32_t XENSTORE_RING_IDX;
-#define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1))
-struct xenstore_domain_interface {
- char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */
- char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */
- XENSTORE_RING_IDX req_cons, req_prod;
- XENSTORE_RING_IDX rsp_cons, rsp_prod;
- uint32_t server_features; /* Bitmap of features supported by the server */
- uint32_t connection;
-};
-
-/* Violating this is very bad. See docs/misc/xenstore.txt. */
-#define XENSTORE_PAYLOAD_MAX 4096
-
-/* Violating these just gets you an error back */
-#define XENSTORE_ABS_PATH_MAX 3072
-#define XENSTORE_REL_PATH_MAX 2048
-
-/* The ability to reconnect a ring */
-#define XENSTORE_SERVER_FEATURE_RECONNECTION 1
-
-/* Valid values for the connection field */
-#define XENSTORE_CONNECTED 0 /* the steady-state */
-#define XENSTORE_RECONNECT 1 /* guest has initiated a reconnect */
-
-#endif /* _XS_WIRE_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * kexec.h - Public portion
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Xen port written by:
- * - Simon 'Horms' Horman <horms@verge.net.au>
- * - Magnus Damm <magnus@valinux.co.jp>
- */
-
-#ifndef _XEN_PUBLIC_KEXEC_H
-#define _XEN_PUBLIC_KEXEC_H
-
-
-/* This file describes the Kexec / Kdump hypercall interface for Xen.
- *
- * Kexec under vanilla Linux allows a user to reboot the physical machine
- * into a new user-specified kernel. The Xen port extends this idea
- * to allow rebooting of the machine from dom0. When kexec for dom0
- * is used to reboot, both the hypervisor and the domains get replaced
- * with some other kernel. It is possible to kexec between vanilla
- * Linux and Xen and back again. Xen to Xen works well too.
- *
- * The hypercall interface for kexec can be divided into three main
- * types of hypercall operations:
- *
- * 1) Range information:
- * This is used by the dom0 kernel to ask the hypervisor about various
- * address information. This information is needed to allow kexec-tools
- * to fill in the ELF headers for /proc/vmcore properly.
- *
- * 2) Load and unload of images:
- * There are no big surprises here, the kexec binary from kexec-tools
- * runs in userspace in dom0. The tool loads/unloads data into the
- * dom0 kernel such as new kernel, initramfs and hypervisor. When
- * loaded the dom0 kernel performs a load hypercall operation, and
- * before releasing all page references the dom0 kernel calls unload.
- *
- * 3) Kexec operation:
- * This is used to start a previously loaded kernel.
- */
-
-#include "xen.h"
-
-#if defined(__i386__) || defined(__x86_64__)
-#define KEXEC_XEN_NO_PAGES 17
-#endif
-
-/*
- * Prototype for this hypercall is:
- * int kexec_op(int cmd, void *args)
- * @cmd == KEXEC_CMD_...
- * KEXEC operation to perform
- * @args == Operation-specific extra arguments (NULL if none).
- */
-
-/*
- * Kexec supports two types of operation:
- * - kexec into a regular kernel, very similar to a standard reboot
- * - KEXEC_TYPE_DEFAULT is used to specify this type
- * - kexec into a special "crash kernel", aka kexec-on-panic
- * - KEXEC_TYPE_CRASH is used to specify this type
- * - parts of our system may be broken at kexec-on-panic time
- * - the code should be kept as simple and self-contained as possible
- */
-
-#define KEXEC_TYPE_DEFAULT 0
-#define KEXEC_TYPE_CRASH 1
-
-
-/* The kexec implementation for Xen allows the user to load two
- * types of kernels, KEXEC_TYPE_DEFAULT and KEXEC_TYPE_CRASH.
- * All data needed for a kexec reboot is kept in one xen_kexec_image_t
- * per "instance". The data mainly consists of machine address lists to pages
- * together with destination addresses. The data in xen_kexec_image_t
- * is passed to the "code page" which is one page of code that performs
- * the final relocations before jumping to the new kernel.
- */
-
-typedef struct xen_kexec_image {
-#if defined(__i386__) || defined(__x86_64__)
- unsigned long page_list[KEXEC_XEN_NO_PAGES];
-#endif
- unsigned long indirection_page;
- unsigned long start_address;
-} xen_kexec_image_t;
-
-/*
- * Perform kexec having previously loaded a kexec or kdump kernel
- * as appropriate.
- * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
- *
- * Control is transferred to the image entry point with the host in
- * the following state.
- *
- * - The image may be executed on any PCPU and all other PCPUs are
- * stopped.
- *
- * - Local interrupts are disabled.
- *
- * - Register values are undefined.
- *
- * - The image segments have writeable 1:1 virtual to machine
- * mappings. The location of any page tables is undefined and these
- * page table frames are not be mapped.
- */
-#define KEXEC_CMD_kexec 0
-typedef struct xen_kexec_exec {
- int type;
-} xen_kexec_exec_t;
-
-/*
- * Load/Unload kernel image for kexec or kdump.
- * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
- * image == relocation information for kexec (ignored for unload) [in]
- */
-#define KEXEC_CMD_kexec_load_v1 1 /* obsolete since 0x00040400 */
-#define KEXEC_CMD_kexec_unload_v1 2 /* obsolete since 0x00040400 */
-typedef struct xen_kexec_load_v1 {
- int type;
- xen_kexec_image_t image;
-} xen_kexec_load_v1_t;
-
-#define KEXEC_RANGE_MA_CRASH 0 /* machine address and size of crash area */
-#define KEXEC_RANGE_MA_XEN 1 /* machine address and size of Xen itself */
-#define KEXEC_RANGE_MA_CPU 2 /* machine address and size of a CPU note */
-#define KEXEC_RANGE_MA_XENHEAP 3 /* machine address and size of xenheap
- * Note that although this is adjacent
- * to Xen it exists in a separate EFI
- * region on ia64, and thus needs to be
- * inserted into iomem_machine separately */
-#define KEXEC_RANGE_MA_BOOT_PARAM 4 /* Obsolete: machine address and size of
- * the ia64_boot_param */
-#define KEXEC_RANGE_MA_EFI_MEMMAP 5 /* machine address and size of
- * of the EFI Memory Map */
-#define KEXEC_RANGE_MA_VMCOREINFO 6 /* machine address and size of vmcoreinfo */
-
-/*
- * Find the address and size of certain memory areas
- * range == KEXEC_RANGE_... [in]
- * nr == physical CPU number (starting from 0) if KEXEC_RANGE_MA_CPU [in]
- * size == number of bytes reserved in window [out]
- * start == address of the first byte in the window [out]
- */
-#define KEXEC_CMD_kexec_get_range 3
-typedef struct xen_kexec_range {
- int range;
- int nr;
- unsigned long size;
- unsigned long start;
-} xen_kexec_range_t;
-
-#if __XEN_INTERFACE_VERSION__ >= 0x00040400
-/*
- * A contiguous chunk of a kexec image and it's destination machine
- * address.
- */
-typedef struct xen_kexec_segment {
- union {
- XEN_GUEST_HANDLE(const_void) h;
- uint64_t _pad;
- } buf;
- uint64_t buf_size;
- uint64_t dest_maddr;
- uint64_t dest_size;
-} xen_kexec_segment_t;
-DEFINE_XEN_GUEST_HANDLE(xen_kexec_segment_t);
-
-/*
- * Load a kexec image into memory.
- *
- * For KEXEC_TYPE_DEFAULT images, the segments may be anywhere in RAM.
- * The image is relocated prior to being executed.
- *
- * For KEXEC_TYPE_CRASH images, each segment of the image must reside
- * in the memory region reserved for kexec (KEXEC_RANGE_MA_CRASH) and
- * the entry point must be within the image. The caller is responsible
- * for ensuring that multiple images do not overlap.
- *
- * All image segments will be loaded to their destination machine
- * addresses prior to being executed. The trailing portion of any
- * segments with a source buffer (from dest_maddr + buf_size to
- * dest_maddr + dest_size) will be zeroed.
- *
- * Segments with no source buffer will be accessible to the image when
- * it is executed.
- */
-
-#define KEXEC_CMD_kexec_load 4
-typedef struct xen_kexec_load {
- uint8_t type; /* One of KEXEC_TYPE_* */
- uint8_t _pad;
- uint16_t arch; /* ELF machine type (EM_*). */
- uint32_t nr_segments;
- union {
- XEN_GUEST_HANDLE(xen_kexec_segment_t) h;
- uint64_t _pad;
- } segments;
- uint64_t entry_maddr; /* image entry point machine address. */
-} xen_kexec_load_t;
-DEFINE_XEN_GUEST_HANDLE(xen_kexec_load_t);
-
-/*
- * Unload a kexec image.
- *
- * Type must be one of KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH.
- */
-#define KEXEC_CMD_kexec_unload 5
-typedef struct xen_kexec_unload {
- uint8_t type;
-} xen_kexec_unload_t;
-DEFINE_XEN_GUEST_HANDLE(xen_kexec_unload_t);
-
-#else /* __XEN_INTERFACE_VERSION__ < 0x00040400 */
-
-#define KEXEC_CMD_kexec_load KEXEC_CMD_kexec_load_v1
-#define KEXEC_CMD_kexec_unload KEXEC_CMD_kexec_unload_v1
-#define xen_kexec_load xen_kexec_load_v1
-#define xen_kexec_load_t xen_kexec_load_v1_t
-
-#endif
-
-#endif /* _XEN_PUBLIC_KEXEC_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * mem_event.h
- *
- * Memory event common structures.
- *
- * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _XEN_PUBLIC_MEM_EVENT_H
-#define _XEN_PUBLIC_MEM_EVENT_H
-
-#include "xen.h"
-#include "io/ring.h"
-
-/* Memory event flags */
-#define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0)
-#define MEM_EVENT_FLAG_DROP_PAGE (1 << 1)
-#define MEM_EVENT_FLAG_EVICT_FAIL (1 << 2)
-#define MEM_EVENT_FLAG_FOREIGN (1 << 3)
-#define MEM_EVENT_FLAG_DUMMY (1 << 4)
-/*
- * Emulate the fault-causing instruction (if set in the event response flags).
- * This will allow the guest to continue execution without lifting the page
- * access restrictions.
- */
-#define MEM_EVENT_FLAG_EMULATE (1 << 5)
-/*
- * Same as MEM_EVENT_FLAG_EMULATE, but with write operations or operations
- * potentially having side effects (like memory mapped or port I/O) disabled.
- */
-#define MEM_EVENT_FLAG_EMULATE_NOWRITE (1 << 6)
-
-/* Reasons for the memory event request */
-#define MEM_EVENT_REASON_UNKNOWN 0 /* typical reason */
-#define MEM_EVENT_REASON_VIOLATION 1 /* access violation, GFN is address */
-#define MEM_EVENT_REASON_CR0 2 /* CR0 was hit: gfn is new CR0 value, gla is previous */
-#define MEM_EVENT_REASON_CR3 3 /* CR3 was hit: gfn is new CR3 value, gla is previous */
-#define MEM_EVENT_REASON_CR4 4 /* CR4 was hit: gfn is new CR4 value, gla is previous */
-#define MEM_EVENT_REASON_INT3 5 /* int3 was hit: gla/gfn are RIP */
-#define MEM_EVENT_REASON_SINGLESTEP 6 /* single step was invoked: gla/gfn are RIP */
-#define MEM_EVENT_REASON_MSR 7 /* MSR was hit: gfn is MSR value, gla is MSR address;
- does NOT honour HVMPME_onchangeonly */
-
-/* Using a custom struct (not hvm_hw_cpu) so as to not fill
- * the mem_event ring buffer too quickly. */
-struct mem_event_regs_x86 {
- uint64_t rax;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rbx;
- uint64_t rsp;
- uint64_t rbp;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t rflags;
- uint64_t dr7;
- uint64_t rip;
- uint64_t cr0;
- uint64_t cr2;
- uint64_t cr3;
- uint64_t cr4;
- uint64_t sysenter_cs;
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
- uint64_t msr_efer;
- uint64_t msr_star;
- uint64_t msr_lstar;
- uint64_t fs_base;
- uint64_t gs_base;
- uint32_t cs_arbytes;
- uint32_t _pad;
-};
-
-typedef struct mem_event_st {
- uint32_t flags;
- uint32_t vcpu_id;
-
- uint64_t gfn;
- uint64_t offset;
- uint64_t gla; /* if gla_valid */
-
- uint32_t p2mt;
-
- uint16_t access_r:1;
- uint16_t access_w:1;
- uint16_t access_x:1;
- uint16_t gla_valid:1;
- uint16_t fault_with_gla:1;
- uint16_t fault_in_gpt:1;
- uint16_t available:10;
-
- uint16_t reason;
- struct mem_event_regs_x86 x86_regs;
-} mem_event_request_t, mem_event_response_t;
-
-DEFINE_RING_TYPES(mem_event, mem_event_request_t, mem_event_response_t);
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * memory.h
- *
- * Memory reservation and information.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_MEMORY_H__
-#define __XEN_PUBLIC_MEMORY_H__
-
-#include "xen.h"
-
-/*
- * Increase or decrease the specified domain's memory reservation. Returns the
- * number of extents successfully allocated or freed.
- * arg == addr of struct xen_memory_reservation.
- */
-#define XENMEM_increase_reservation 0
-#define XENMEM_decrease_reservation 1
-#define XENMEM_populate_physmap 6
-
-#if __XEN_INTERFACE_VERSION__ >= 0x00030209
-/*
- * Maximum # bits addressable by the user of the allocated region (e.g., I/O
- * devices often have a 32-bit limitation even in 64-bit systems). If zero
- * then the user has no addressing restriction. This field is not used by
- * XENMEM_decrease_reservation.
- */
-#define XENMEMF_address_bits(x) (x)
-#define XENMEMF_get_address_bits(x) ((x) & 0xffu)
-/* NUMA node to allocate from. */
-#define XENMEMF_node(x) (((x) + 1) << 8)
-#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu)
-/* Flag to populate physmap with populate-on-demand entries */
-#define XENMEMF_populate_on_demand (1<<16)
-/* Flag to request allocation only from the node specified */
-#define XENMEMF_exact_node_request (1<<17)
-#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request)
-#endif
-
-struct xen_memory_reservation {
-
- /*
- * XENMEM_increase_reservation:
- * OUT: MFN (*not* GMFN) bases of extents that were allocated
- * XENMEM_decrease_reservation:
- * IN: GMFN bases of extents to free
- * XENMEM_populate_physmap:
- * IN: GPFN bases of extents to populate with memory
- * OUT: GMFN bases of extents that were allocated
- * (NB. This command also updates the mach_to_phys translation table)
- * XENMEM_claim_pages:
- * IN: must be zero
- */
- XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
-
- /* Number of extents, and size/alignment of each (2^extent_order pages). */
- xen_ulong_t nr_extents;
- unsigned int extent_order;
-
-#if __XEN_INTERFACE_VERSION__ >= 0x00030209
- /* XENMEMF flags. */
- unsigned int mem_flags;
-#else
- unsigned int address_bits;
-#endif
-
- /*
- * Domain whose reservation is being changed.
- * Unprivileged domains can specify only DOMID_SELF.
- */
- domid_t domid;
-};
-typedef struct xen_memory_reservation xen_memory_reservation_t;
-DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);
-
-/*
- * An atomic exchange of memory pages. If return code is zero then
- * @out.extent_list provides GMFNs of the newly-allocated memory.
- * Returns zero on complete success, otherwise a negative error code.
- * On complete success then always @nr_exchanged == @in.nr_extents.
- * On partial success @nr_exchanged indicates how much work was done.
- */
-#define XENMEM_exchange 11
-struct xen_memory_exchange {
- /*
- * [IN] Details of memory extents to be exchanged (GMFN bases).
- * Note that @in.address_bits is ignored and unused.
- */
- struct xen_memory_reservation in;
-
- /*
- * [IN/OUT] Details of new memory extents.
- * We require that:
- * 1. @in.domid == @out.domid
- * 2. @in.nr_extents << @in.extent_order ==
- * @out.nr_extents << @out.extent_order
- * 3. @in.extent_start and @out.extent_start lists must not overlap
- * 4. @out.extent_start lists GPFN bases to be populated
- * 5. @out.extent_start is overwritten with allocated GMFN bases
- */
- struct xen_memory_reservation out;
-
- /*
- * [OUT] Number of input extents that were successfully exchanged:
- * 1. The first @nr_exchanged input extents were successfully
- * deallocated.
- * 2. The corresponding first entries in the output extent list correctly
- * indicate the GMFNs that were successfully exchanged.
- * 3. All other input and output extents are untouched.
- * 4. If not all input exents are exchanged then the return code of this
- * command will be non-zero.
- * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
- */
- xen_ulong_t nr_exchanged;
-};
-typedef struct xen_memory_exchange xen_memory_exchange_t;
-DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
-
-/*
- * Returns the maximum machine frame number of mapped RAM in this system.
- * This command always succeeds (it never returns an error code).
- * arg == NULL.
- */
-#define XENMEM_maximum_ram_page 2
-
-/*
- * Returns the current or maximum memory reservation, in pages, of the
- * specified domain (may be DOMID_SELF). Returns -ve errcode on failure.
- * arg == addr of domid_t.
- */
-#define XENMEM_current_reservation 3
-#define XENMEM_maximum_reservation 4
-
-/*
- * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
- */
-#define XENMEM_maximum_gpfn 14
-
-/*
- * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
- * mapping table. Architectures which do not have a m2p table do not implement
- * this command.
- * arg == addr of xen_machphys_mfn_list_t.
- */
-#define XENMEM_machphys_mfn_list 5
-struct xen_machphys_mfn_list {
- /*
- * Size of the 'extent_start' array. Fewer entries will be filled if the
- * machphys table is smaller than max_extents * 2MB.
- */
- unsigned int max_extents;
-
- /*
- * Pointer to buffer to fill with list of extent starts. If there are
- * any large discontiguities in the machine address space, 2MB gaps in
- * the machphys table will be represented by an MFN base of zero.
- */
- XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
-
- /*
- * Number of extents written to the above array. This will be smaller
- * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
- */
- unsigned int nr_extents;
-};
-typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t;
-DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
-
-/*
- * For a compat caller, this is identical to XENMEM_machphys_mfn_list.
- *
- * For a non compat caller, this functions similarly to
- * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibility
- * m2p table.
- */
-#define XENMEM_machphys_compat_mfn_list 25
-
-/*
- * Returns the location in virtual address space of the machine_to_phys
- * mapping table. Architectures which do not have a m2p table, or which do not
- * map it by default into guest address space, do not implement this command.
- * arg == addr of xen_machphys_mapping_t.
- */
-#define XENMEM_machphys_mapping 12
-struct xen_machphys_mapping {
- xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */
- xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */
-};
-typedef struct xen_machphys_mapping xen_machphys_mapping_t;
-DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
-
-/* Source mapping space. */
-/* ` enum phys_map_space { */
-#define XENMAPSPACE_shared_info 0 /* shared info page */
-#define XENMAPSPACE_grant_table 1 /* grant table page */
-#define XENMAPSPACE_gmfn 2 /* GMFN */
-#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */
-#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
- * XENMEM_add_to_physmap_batch only. */
-/* ` } */
-
-/*
- * Sets the GPFN at which a particular page appears in the specified guest's
- * pseudophysical address space.
- * arg == addr of xen_add_to_physmap_t.
- */
-#define XENMEM_add_to_physmap 7
-struct xen_add_to_physmap {
- /* Which domain to change the mapping for. */
- domid_t domid;
-
- /* Number of pages to go through for gmfn_range */
- uint16_t size;
-
- unsigned int space; /* => enum phys_map_space */
-
-#define XENMAPIDX_grant_table_status 0x80000000
-
- /* Index into space being mapped. */
- xen_ulong_t idx;
-
- /* GPFN in domid where the source mapping page should appear. */
- xen_pfn_t gpfn;
-};
-typedef struct xen_add_to_physmap xen_add_to_physmap_t;
-DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
-
-/* A batched version of add_to_physmap. */
-#define XENMEM_add_to_physmap_batch 23
-struct xen_add_to_physmap_batch {
- /* IN */
- /* Which domain to change the mapping for. */
- domid_t domid;
- uint16_t space; /* => enum phys_map_space */
-
- /* Number of pages to go through */
- uint16_t size;
- domid_t foreign_domid; /* IFF gmfn_foreign */
-
- /* Indexes into space being mapped. */
- XEN_GUEST_HANDLE(xen_ulong_t) idxs;
-
- /* GPFN in domid where the source mapping page should appear. */
- XEN_GUEST_HANDLE(xen_pfn_t) gpfns;
-
- /* OUT */
-
- /* Per index error code. */
- XEN_GUEST_HANDLE(int) errs;
-};
-typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t;
-DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t);
-
-#if __XEN_INTERFACE_VERSION__ < 0x00040400
-#define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch
-#define xen_add_to_physmap_range xen_add_to_physmap_batch
-typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t;
-DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t);
-#endif
-
-/*
- * Unmaps the page appearing at a particular GPFN from the specified guest's
- * pseudophysical address space.
- * arg == addr of xen_remove_from_physmap_t.
- */
-#define XENMEM_remove_from_physmap 15
-struct xen_remove_from_physmap {
- /* Which domain to change the mapping for. */
- domid_t domid;
-
- /* GPFN of the current mapping of the page. */
- xen_pfn_t gpfn;
-};
-typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
-DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
-
-/*** REMOVED ***/
-/*#define XENMEM_translate_gpfn_list 8*/
-
-/*
- * Returns the pseudo-physical memory map as it was when the domain
- * was started (specified by XENMEM_set_memory_map).
- * arg == addr of xen_memory_map_t.
- */
-#define XENMEM_memory_map 9
-struct xen_memory_map {
- /*
- * On call the number of entries which can be stored in buffer. On
- * return the number of entries which have been stored in
- * buffer.
- */
- unsigned int nr_entries;
-
- /*
- * Entries in the buffer are in the same format as returned by the
- * BIOS INT 0x15 EAX=0xE820 call.
- */
- XEN_GUEST_HANDLE(void) buffer;
-};
-typedef struct xen_memory_map xen_memory_map_t;
-DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
-
-/*
- * Returns the real physical memory map. Passes the same structure as
- * XENMEM_memory_map.
- * arg == addr of xen_memory_map_t.
- */
-#define XENMEM_machine_memory_map 10
-
-/*
- * Set the pseudo-physical memory map of a domain, as returned by
- * XENMEM_memory_map.
- * arg == addr of xen_foreign_memory_map_t.
- */
-#define XENMEM_set_memory_map 13
-struct xen_foreign_memory_map {
- domid_t domid;
- struct xen_memory_map map;
-};
-typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
-DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
-
-#define XENMEM_set_pod_target 16
-#define XENMEM_get_pod_target 17
-struct xen_pod_target {
- /* IN */
- uint64_t target_pages;
- /* OUT */
- uint64_t tot_pages;
- uint64_t pod_cache_pages;
- uint64_t pod_entries;
- /* IN */
- domid_t domid;
-};
-typedef struct xen_pod_target xen_pod_target_t;
-
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-#ifndef uint64_aligned_t
-#define uint64_aligned_t uint64_t
-#endif
-
-/*
- * Get the number of MFNs saved through memory sharing.
- * The call never fails.
- */
-#define XENMEM_get_sharing_freed_pages 18
-#define XENMEM_get_sharing_shared_pages 19
-
-#define XENMEM_paging_op 20
-#define XENMEM_paging_op_nominate 0
-#define XENMEM_paging_op_evict 1
-#define XENMEM_paging_op_prep 2
-
-struct xen_mem_event_op {
- uint8_t op; /* XENMEM_*_op_* */
- domid_t domain;
-
-
- /* PAGING_PREP IN: buffer to immediately fill page in */
- uint64_aligned_t buffer;
- /* Other OPs */
- uint64_aligned_t gfn; /* IN: gfn of page being operated on */
-};
-typedef struct xen_mem_event_op xen_mem_event_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mem_event_op_t);
-
-#define XENMEM_access_op 21
-#define XENMEM_access_op_resume 0
-#define XENMEM_access_op_set_access 1
-#define XENMEM_access_op_get_access 2
-
-typedef enum {
- XENMEM_access_n,
- XENMEM_access_r,
- XENMEM_access_w,
- XENMEM_access_rw,
- XENMEM_access_x,
- XENMEM_access_rx,
- XENMEM_access_wx,
- XENMEM_access_rwx,
- /*
- * Page starts off as r-x, but automatically
- * change to r-w on a write
- */
- XENMEM_access_rx2rw,
- /*
- * Log access: starts off as n, automatically
- * goes to rwx, generating an event without
- * pausing the vcpu
- */
- XENMEM_access_n2rwx,
- /* Take the domain default */
- XENMEM_access_default
-} xenmem_access_t;
-
-struct xen_mem_access_op {
- /* XENMEM_access_op_* */
- uint8_t op;
- /* xenmem_access_t */
- uint8_t access;
- domid_t domid;
- /*
- * Number of pages for set op
- * Ignored on setting default access and other ops
- */
- uint32_t nr;
- /*
- * First pfn for set op
- * pfn for get op
- * ~0ull is used to set and get the default access for pages
- */
- uint64_aligned_t pfn;
-};
-typedef struct xen_mem_access_op xen_mem_access_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t);
-
-#define XENMEM_sharing_op 22
-#define XENMEM_sharing_op_nominate_gfn 0
-#define XENMEM_sharing_op_nominate_gref 1
-#define XENMEM_sharing_op_share 2
-#define XENMEM_sharing_op_resume 3
-#define XENMEM_sharing_op_debug_gfn 4
-#define XENMEM_sharing_op_debug_mfn 5
-#define XENMEM_sharing_op_debug_gref 6
-#define XENMEM_sharing_op_add_physmap 7
-#define XENMEM_sharing_op_audit 8
-
-#define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10)
-#define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9)
-
-/* The following allows sharing of grant refs. This is useful
- * for sharing utilities sitting as "filters" in IO backends
- * (e.g. memshr + blktap(2)). The IO backend is only exposed
- * to grant references, and this allows sharing of the grefs */
-#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (1ULL << 62)
-
-#define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \
- (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val)
-#define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \
- ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)
-#define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \
- ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG))
-
-struct xen_mem_sharing_op {
- uint8_t op; /* XENMEM_sharing_op_* */
- domid_t domain;
-
- union {
- struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */
- union {
- uint64_aligned_t gfn; /* IN: gfn to nominate */
- uint32_t grant_ref; /* IN: grant ref to nominate */
- } u;
- uint64_aligned_t handle; /* OUT: the handle */
- } nominate;
- struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */
- uint64_aligned_t source_gfn; /* IN: the gfn of the source page */
- uint64_aligned_t source_handle; /* IN: handle to the source page */
- uint64_aligned_t client_gfn; /* IN: the client gfn */
- uint64_aligned_t client_handle; /* IN: handle to the client page */
- domid_t client_domain; /* IN: the client domain id */
- } share;
- struct mem_sharing_op_debug { /* OP_DEBUG_xxx */
- union {
- uint64_aligned_t gfn; /* IN: gfn to debug */
- uint64_aligned_t mfn; /* IN: mfn to debug */
- uint32_t gref; /* IN: gref to debug */
- } u;
- } debug;
- } u;
-};
-typedef struct xen_mem_sharing_op xen_mem_sharing_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t);
-
-/*
- * Attempt to stake a claim for a domain on a quantity of pages
- * of system RAM, but _not_ assign specific pageframes. Only
- * arithmetic is performed so the hypercall is very fast and need
- * not be preemptible, thus sidestepping time-of-check-time-of-use
- * races for memory allocation. Returns 0 if the hypervisor page
- * allocator has atomically and successfully claimed the requested
- * number of pages, else non-zero.
- *
- * Any domain may have only one active claim. When sufficient memory
- * has been allocated to resolve the claim, the claim silently expires.
- * Claiming zero pages effectively resets any outstanding claim and
- * is always successful.
- *
- * Note that a valid claim may be staked even after memory has been
- * allocated for a domain. In this case, the claim is not incremental,
- * i.e. if the domain's tot_pages is 3, and a claim is staked for 10,
- * only 7 additional pages are claimed.
- *
- * Caller must be privileged or the hypercall fails.
- */
-#define XENMEM_claim_pages 24
-
-/*
- * XENMEM_claim_pages flags - the are no flags at this time.
- * The zero value is appropiate.
- */
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
-/*
- * XENMEM_get_vnumainfo used by guest to get
- * vNUMA topology from hypervisor.
- */
-#define XENMEM_get_vnumainfo 26
-
-/* vNUMA node memory ranges */
-struct xen_vmemrange {
- uint64_t start, end;
- unsigned int flags;
- unsigned int nid;
-};
-typedef struct xen_vmemrange xen_vmemrange_t;
-DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t);
-
-/*
- * vNUMA topology specifies vNUMA node number, distance table,
- * memory ranges and vcpu mapping provided for guests.
- * XENMEM_get_vnumainfo hypercall expects to see from guest
- * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory.
- * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus
- * copied back to guest. Domain returns expected values of nr_vnodes,
- * nr_vmemranges and nr_vcpus to guest if the values where incorrect.
- */
-struct xen_vnuma_topology_info {
- /* IN */
- domid_t domid;
- uint16_t pad;
- /* IN/OUT */
- unsigned int nr_vnodes;
- unsigned int nr_vcpus;
- unsigned int nr_vmemranges;
- /* OUT */
- union {
- XEN_GUEST_HANDLE(uint) h;
- uint64_t pad;
- } vdistance;
- union {
- XEN_GUEST_HANDLE(uint) h;
- uint64_t pad;
- } vcpu_to_vnode;
- union {
- XEN_GUEST_HANDLE(xen_vmemrange_t) h;
- uint64_t pad;
- } vmemrange;
-};
-typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t;
-DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t);
-
-/* Next available subop number is 27 */
-
-#endif /* __XEN_PUBLIC_MEMORY_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * nmi.h
- *
- * NMI callback registration and reason codes.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_NMI_H__
-#define __XEN_PUBLIC_NMI_H__
-
-#include "xen.h"
-
-/*
- * NMI reason codes:
- * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
- */
- /* I/O-check error reported via ISA port 0x61, bit 6. */
-#define _XEN_NMIREASON_io_error 0
-#define XEN_NMIREASON_io_error (1UL << _XEN_NMIREASON_io_error)
- /* PCI SERR reported via ISA port 0x61, bit 7. */
-#define _XEN_NMIREASON_pci_serr 1
-#define XEN_NMIREASON_pci_serr (1UL << _XEN_NMIREASON_pci_serr)
-#if __XEN_INTERFACE_VERSION__ < 0x00040300 /* legacy alias of the above */
- /* Parity error reported via ISA port 0x61, bit 7. */
-#define _XEN_NMIREASON_parity_error 1
-#define XEN_NMIREASON_parity_error (1UL << _XEN_NMIREASON_parity_error)
-#endif
- /* Unknown hardware-generated NMI. */
-#define _XEN_NMIREASON_unknown 2
-#define XEN_NMIREASON_unknown (1UL << _XEN_NMIREASON_unknown)
-
-/*
- * long nmi_op(unsigned int cmd, void *arg)
- * NB. All ops return zero on success, else a negative error code.
- */
-
-/*
- * Register NMI callback for this (calling) VCPU. Currently this only makes
- * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
- * arg == pointer to xennmi_callback structure.
- */
-#define XENNMI_register_callback 0
-struct xennmi_callback {
- unsigned long handler_address;
- unsigned long pad;
-};
-typedef struct xennmi_callback xennmi_callback_t;
-DEFINE_XEN_GUEST_HANDLE(xennmi_callback_t);
-
-/*
- * Deregister NMI callback for this (calling) VCPU.
- * arg == NULL.
- */
-#define XENNMI_unregister_callback 1
-
-#endif /* __XEN_PUBLIC_NMI_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __XEN_PUBLIC_PHYSDEV_H__
-#define __XEN_PUBLIC_PHYSDEV_H__
-
-#include "xen.h"
-
-/*
- * Prototype for this hypercall is:
- * int physdev_op(int cmd, void *args)
- * @cmd == PHYSDEVOP_??? (physdev operation).
- * @args == Operation-specific extra arguments (NULL if none).
- */
-
-/*
- * Notify end-of-interrupt (EOI) for the specified IRQ.
- * @arg == pointer to physdev_eoi structure.
- */
-#define PHYSDEVOP_eoi 12
-struct physdev_eoi {
- /* IN */
- uint32_t irq;
-};
-typedef struct physdev_eoi physdev_eoi_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
-
-/*
- * Register a shared page for the hypervisor to indicate whether the guest
- * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
- * once the guest used this function in that the associated event channel
- * will automatically get unmasked. The page registered is used as a bit
- * array indexed by Xen's PIRQ value.
- */
-#define PHYSDEVOP_pirq_eoi_gmfn_v1 17
-/*
- * Register a shared page for the hypervisor to indicate whether the
- * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to
- * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of
- * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by
- * Xen's PIRQ value.
- */
-#define PHYSDEVOP_pirq_eoi_gmfn_v2 28
-struct physdev_pirq_eoi_gmfn {
- /* IN */
- xen_pfn_t gmfn;
-};
-typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
-
-/*
- * Query the status of an IRQ line.
- * @arg == pointer to physdev_irq_status_query structure.
- */
-#define PHYSDEVOP_irq_status_query 5
-struct physdev_irq_status_query {
- /* IN */
- uint32_t irq;
- /* OUT */
- uint32_t flags; /* XENIRQSTAT_* */
-};
-typedef struct physdev_irq_status_query physdev_irq_status_query_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
-
-/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
-#define _XENIRQSTAT_needs_eoi (0)
-#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi)
-
-/* IRQ shared by multiple guests? */
-#define _XENIRQSTAT_shared (1)
-#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared)
-
-/*
- * Set the current VCPU's I/O privilege level.
- * @arg == pointer to physdev_set_iopl structure.
- */
-#define PHYSDEVOP_set_iopl 6
-struct physdev_set_iopl {
- /* IN */
- uint32_t iopl;
-};
-typedef struct physdev_set_iopl physdev_set_iopl_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
-
-/*
- * Set the current VCPU's I/O-port permissions bitmap.
- * @arg == pointer to physdev_set_iobitmap structure.
- */
-#define PHYSDEVOP_set_iobitmap 7
-struct physdev_set_iobitmap {
- /* IN */
-#if __XEN_INTERFACE_VERSION__ >= 0x00030205
- XEN_GUEST_HANDLE(uint8) bitmap;
-#else
- uint8_t *bitmap;
-#endif
- uint32_t nr_ports;
-};
-typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
-
-/*
- * Read or write an IO-APIC register.
- * @arg == pointer to physdev_apic structure.
- */
-#define PHYSDEVOP_apic_read 8
-#define PHYSDEVOP_apic_write 9
-struct physdev_apic {
- /* IN */
- unsigned long apic_physbase;
- uint32_t reg;
- /* IN or OUT */
- uint32_t value;
-};
-typedef struct physdev_apic physdev_apic_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
-
-/*
- * Allocate or free a physical upcall vector for the specified IRQ line.
- * @arg == pointer to physdev_irq structure.
- */
-#define PHYSDEVOP_alloc_irq_vector 10
-#define PHYSDEVOP_free_irq_vector 11
-struct physdev_irq {
- /* IN */
- uint32_t irq;
- /* IN or OUT */
- uint32_t vector;
-};
-typedef struct physdev_irq physdev_irq_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
-
-#define MAP_PIRQ_TYPE_MSI 0x0
-#define MAP_PIRQ_TYPE_GSI 0x1
-#define MAP_PIRQ_TYPE_UNKNOWN 0x2
-#define MAP_PIRQ_TYPE_MSI_SEG 0x3
-#define MAP_PIRQ_TYPE_MULTI_MSI 0x4
-
-#define PHYSDEVOP_map_pirq 13
-struct physdev_map_pirq {
- domid_t domid;
- /* IN */
- int type;
- /* IN (ignored for ..._MULTI_MSI) */
- int index;
- /* IN or OUT */
- int pirq;
- /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */
- int bus;
- /* IN */
- int devfn;
- /* IN (also OUT for ..._MULTI_MSI) */
- int entry_nr;
- /* IN */
- uint64_t table_base;
-};
-typedef struct physdev_map_pirq physdev_map_pirq_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
-
-#define PHYSDEVOP_unmap_pirq 14
-struct physdev_unmap_pirq {
- domid_t domid;
- /* IN */
- int pirq;
-};
-
-typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
-
-#define PHYSDEVOP_manage_pci_add 15
-#define PHYSDEVOP_manage_pci_remove 16
-struct physdev_manage_pci {
- /* IN */
- uint8_t bus;
- uint8_t devfn;
-};
-
-typedef struct physdev_manage_pci physdev_manage_pci_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
-
-#define PHYSDEVOP_restore_msi 19
-struct physdev_restore_msi {
- /* IN */
- uint8_t bus;
- uint8_t devfn;
-};
-typedef struct physdev_restore_msi physdev_restore_msi_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t);
-
-#define PHYSDEVOP_manage_pci_add_ext 20
-struct physdev_manage_pci_ext {
- /* IN */
- uint8_t bus;
- uint8_t devfn;
- unsigned is_extfn;
- unsigned is_virtfn;
- struct {
- uint8_t bus;
- uint8_t devfn;
- } physfn;
-};
-
-typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t);
-
-/*
- * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
- * hypercall since 0x00030202.
- */
-struct physdev_op {
- uint32_t cmd;
- union {
- struct physdev_irq_status_query irq_status_query;
- struct physdev_set_iopl set_iopl;
- struct physdev_set_iobitmap set_iobitmap;
- struct physdev_apic apic_op;
- struct physdev_irq irq_op;
- } u;
-};
-typedef struct physdev_op physdev_op_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
-
-#define PHYSDEVOP_setup_gsi 21
-struct physdev_setup_gsi {
- int gsi;
- /* IN */
- uint8_t triggering;
- /* IN */
- uint8_t polarity;
- /* IN */
-};
-
-typedef struct physdev_setup_gsi physdev_setup_gsi_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
-
-/* leave PHYSDEVOP 22 free */
-
-/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
- * the hypercall returns a free pirq */
-#define PHYSDEVOP_get_free_pirq 23
-struct physdev_get_free_pirq {
- /* IN */
- int type;
- /* OUT */
- uint32_t pirq;
-};
-
-typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);
-
-#define XEN_PCI_MMCFG_RESERVED 0x1
-
-#define PHYSDEVOP_pci_mmcfg_reserved 24
-struct physdev_pci_mmcfg_reserved {
- uint64_t address;
- uint16_t segment;
- uint8_t start_bus;
- uint8_t end_bus;
- uint32_t flags;
-};
-typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t);
-
-#define XEN_PCI_DEV_EXTFN 0x1
-#define XEN_PCI_DEV_VIRTFN 0x2
-#define XEN_PCI_DEV_PXM 0x4
-
-#define PHYSDEVOP_pci_device_add 25
-struct physdev_pci_device_add {
- /* IN */
- uint16_t seg;
- uint8_t bus;
- uint8_t devfn;
- uint32_t flags;
- struct {
- uint8_t bus;
- uint8_t devfn;
- } physfn;
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- uint32_t optarr[];
-#elif defined(__GNUC__)
- uint32_t optarr[0];
-#endif
-};
-typedef struct physdev_pci_device_add physdev_pci_device_add_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t);
-
-#define PHYSDEVOP_pci_device_remove 26
-#define PHYSDEVOP_restore_msi_ext 27
-/*
- * Dom0 should use these two to announce MMIO resources assigned to
- * MSI-X capable devices won't (prepare) or may (release) change.
- */
-#define PHYSDEVOP_prepare_msix 30
-#define PHYSDEVOP_release_msix 31
-struct physdev_pci_device {
- /* IN */
- uint16_t seg;
- uint8_t bus;
- uint8_t devfn;
-};
-typedef struct physdev_pci_device physdev_pci_device_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t);
-
-#define PHYSDEVOP_DBGP_RESET_PREPARE 1
-#define PHYSDEVOP_DBGP_RESET_DONE 2
-
-#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0
-#define PHYSDEVOP_DBGP_BUS_PCI 1
-
-#define PHYSDEVOP_dbgp_op 29
-struct physdev_dbgp_op {
- /* IN */
- uint8_t op;
- uint8_t bus;
- union {
- struct physdev_pci_device pci;
- } u;
-};
-typedef struct physdev_dbgp_op physdev_dbgp_op_t;
-DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t);
-
-/*
- * Notify that some PIRQ-bound event channels have been unmasked.
- * ** This command is obsolete since interface version 0x00030202 and is **
- * ** unsupported by newer versions of Xen. **
- */
-#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
-
-#if __XEN_INTERFACE_VERSION__ < 0x00040600
-/*
- * These all-capitals physdev operation names are superceded by the new names
- * (defined above) since interface version 0x00030202. The guard above was
- * added post-4.5 only though and hence shouldn't check for 0x00030202.
- */
-#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
-#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
-#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
-#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
-#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
-#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
-#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector
-#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
-#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared
-#endif
-
-#if __XEN_INTERFACE_VERSION__ < 0x00040200
-#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1
-#else
-#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2
-#endif
-
-#endif /* __XEN_PUBLIC_PHYSDEV_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * platform.h
- *
- * Hardware platform operations. Intended for use by domain-0 kernel.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2002-2006, K Fraser
- */
-
-#ifndef __XEN_PUBLIC_PLATFORM_H__
-#define __XEN_PUBLIC_PLATFORM_H__
-
-#include "xen.h"
-
-#define XENPF_INTERFACE_VERSION 0x03000001
-
-/*
- * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
- * 1 January, 1970 if the current system time was <system_time>.
- */
-#define XENPF_settime 17
-struct xenpf_settime {
- /* IN variables. */
- uint32_t secs;
- uint32_t nsecs;
- uint64_t system_time;
-};
-typedef struct xenpf_settime xenpf_settime_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t);
-
-/*
- * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
- * On x86, @type is an architecture-defined MTRR memory type.
- * On success, returns the MTRR that was used (@reg) and a handle that can
- * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting.
- * (x86-specific).
- */
-#define XENPF_add_memtype 31
-struct xenpf_add_memtype {
- /* IN variables. */
- xen_pfn_t mfn;
- uint64_t nr_mfns;
- uint32_t type;
- /* OUT variables. */
- uint32_t handle;
- uint32_t reg;
-};
-typedef struct xenpf_add_memtype xenpf_add_memtype_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_add_memtype_t);
-
-/*
- * Tear down an existing memory-range type. If @handle is remembered then it
- * should be passed in to accurately tear down the correct setting (in case
- * of overlapping memory regions with differing types). If it is not known
- * then @handle should be set to zero. In all cases @reg must be set.
- * (x86-specific).
- */
-#define XENPF_del_memtype 32
-struct xenpf_del_memtype {
- /* IN variables. */
- uint32_t handle;
- uint32_t reg;
-};
-typedef struct xenpf_del_memtype xenpf_del_memtype_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_del_memtype_t);
-
-/* Read current type of an MTRR (x86-specific). */
-#define XENPF_read_memtype 33
-struct xenpf_read_memtype {
- /* IN variables. */
- uint32_t reg;
- /* OUT variables. */
- xen_pfn_t mfn;
- uint64_t nr_mfns;
- uint32_t type;
-};
-typedef struct xenpf_read_memtype xenpf_read_memtype_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_read_memtype_t);
-
-#define XENPF_microcode_update 35
-struct xenpf_microcode_update {
- /* IN variables. */
- XEN_GUEST_HANDLE(const_void) data;/* Pointer to microcode data */
- uint32_t length; /* Length of microcode data. */
-};
-typedef struct xenpf_microcode_update xenpf_microcode_update_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_microcode_update_t);
-
-#define XENPF_platform_quirk 39
-#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */
-#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */
-#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */
-struct xenpf_platform_quirk {
- /* IN variables. */
- uint32_t quirk_id;
-};
-typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
-
-#define XENPF_efi_runtime_call 49
-#define XEN_EFI_get_time 1
-#define XEN_EFI_set_time 2
-#define XEN_EFI_get_wakeup_time 3
-#define XEN_EFI_set_wakeup_time 4
-#define XEN_EFI_get_next_high_monotonic_count 5
-#define XEN_EFI_get_variable 6
-#define XEN_EFI_set_variable 7
-#define XEN_EFI_get_next_variable_name 8
-#define XEN_EFI_query_variable_info 9
-#define XEN_EFI_query_capsule_capabilities 10
-#define XEN_EFI_update_capsule 11
-struct xenpf_efi_runtime_call {
- uint32_t function;
- /*
- * This field is generally used for per sub-function flags (defined
- * below), except for the XEN_EFI_get_next_high_monotonic_count case,
- * where it holds the single returned value.
- */
- uint32_t misc;
- xen_ulong_t status;
- union {
-#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001
- struct {
- struct xenpf_efi_time {
- uint16_t year;
- uint8_t month;
- uint8_t day;
- uint8_t hour;
- uint8_t min;
- uint8_t sec;
- uint32_t ns;
- int16_t tz;
- uint8_t daylight;
- } time;
- uint32_t resolution;
- uint32_t accuracy;
- } get_time;
-
- struct xenpf_efi_time set_time;
-
-#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001
-#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002
- struct xenpf_efi_time get_wakeup_time;
-
-#define XEN_EFI_SET_WAKEUP_TIME_ENABLE 0x00000001
-#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002
- struct xenpf_efi_time set_wakeup_time;
-
-#define XEN_EFI_VARIABLE_NON_VOLATILE 0x00000001
-#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
-#define XEN_EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
- struct {
- XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
- xen_ulong_t size;
- XEN_GUEST_HANDLE(void) data;
- struct xenpf_efi_guid {
- uint32_t data1;
- uint16_t data2;
- uint16_t data3;
- uint8_t data4[8];
- } vendor_guid;
- } get_variable, set_variable;
-
- struct {
- xen_ulong_t size;
- XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
- struct xenpf_efi_guid vendor_guid;
- } get_next_variable_name;
-
-#define XEN_EFI_VARINFO_BOOT_SNAPSHOT 0x00000001
- struct {
- uint32_t attr;
- uint64_t max_store_size;
- uint64_t remain_store_size;
- uint64_t max_size;
- } query_variable_info;
-
- struct {
- XEN_GUEST_HANDLE(void) capsule_header_array;
- xen_ulong_t capsule_count;
- uint64_t max_capsule_size;
- uint32_t reset_type;
- } query_capsule_capabilities;
-
- struct {
- XEN_GUEST_HANDLE(void) capsule_header_array;
- xen_ulong_t capsule_count;
- uint64_t sg_list; /* machine address */
- } update_capsule;
- } u;
-};
-typedef struct xenpf_efi_runtime_call xenpf_efi_runtime_call_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t);
-
-#define XENPF_firmware_info 50
-#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
-#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
-#define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */
-#define XEN_FW_EFI_INFO 4 /* from EFI */
-#define XEN_FW_EFI_VERSION 0
-#define XEN_FW_EFI_CONFIG_TABLE 1
-#define XEN_FW_EFI_VENDOR 2
-#define XEN_FW_EFI_MEM_INFO 3
-#define XEN_FW_EFI_RT_VERSION 4
-#define XEN_FW_EFI_PCI_ROM 5
-#define XEN_FW_KBD_SHIFT_FLAGS 5
-struct xenpf_firmware_info {
- /* IN variables. */
- uint32_t type;
- uint32_t index;
- /* OUT variables. */
- union {
- struct {
- /* Int13, Fn48: Check Extensions Present. */
- uint8_t device; /* %dl: bios device number */
- uint8_t version; /* %ah: major version */
- uint16_t interface_support; /* %cx: support bitmap */
- /* Int13, Fn08: Legacy Get Device Parameters. */
- uint16_t legacy_max_cylinder; /* %cl[7:6]:%ch: max cyl # */
- uint8_t legacy_max_head; /* %dh: max head # */
- uint8_t legacy_sectors_per_track; /* %cl[5:0]: max sector # */
- /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
- /* NB. First uint16_t of buffer must be set to buffer size. */
- XEN_GUEST_HANDLE(void) edd_params;
- } disk_info; /* XEN_FW_DISK_INFO */
- struct {
- uint8_t device; /* bios device number */
- uint32_t mbr_signature; /* offset 0x1b8 in mbr */
- } disk_mbr_signature; /* XEN_FW_DISK_MBR_SIGNATURE */
- struct {
- /* Int10, AX=4F15: Get EDID info. */
- uint8_t capabilities;
- uint8_t edid_transfer_time;
- /* must refer to 128-byte buffer */
- XEN_GUEST_HANDLE(uint8) edid;
- } vbeddc_info; /* XEN_FW_VBEDDC_INFO */
- union xenpf_efi_info {
- uint32_t version;
- struct {
- uint64_t addr; /* EFI_CONFIGURATION_TABLE */
- uint32_t nent;
- } cfg;
- struct {
- uint32_t revision;
- uint32_t bufsz; /* input, in bytes */
- XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
- } vendor;
- struct {
- uint64_t addr;
- uint64_t size;
- uint64_t attr;
- uint32_t type;
- } mem;
- struct {
- /* IN variables */
- uint16_t segment;
- uint8_t bus;
- uint8_t devfn;
- uint16_t vendor;
- uint16_t devid;
- /* OUT variables */
- uint64_t address;
- xen_ulong_t size;
- } pci_rom;
- } efi_info; /* XEN_FW_EFI_INFO */
-
- /* Int16, Fn02: Get keyboard shift flags. */
- uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
- } u;
-};
-typedef struct xenpf_firmware_info xenpf_firmware_info_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
-
-#define XENPF_enter_acpi_sleep 51
-struct xenpf_enter_acpi_sleep {
- /* IN variables */
-#if __XEN_INTERFACE_VERSION__ < 0x00040300
- uint16_t pm1a_cnt_val; /* PM1a control value. */
- uint16_t pm1b_cnt_val; /* PM1b control value. */
-#else
- uint16_t val_a; /* PM1a control / sleep type A. */
- uint16_t val_b; /* PM1b control / sleep type B. */
-#endif
- uint32_t sleep_state; /* Which state to enter (Sn). */
-#define XENPF_ACPI_SLEEP_EXTENDED 0x00000001
- uint32_t flags; /* XENPF_ACPI_SLEEP_*. */
-};
-typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t);
-
-#define XENPF_change_freq 52
-struct xenpf_change_freq {
- /* IN variables */
- uint32_t flags; /* Must be zero. */
- uint32_t cpu; /* Physical cpu. */
- uint64_t freq; /* New frequency (Hz). */
-};
-typedef struct xenpf_change_freq xenpf_change_freq_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t);
-
-/*
- * Get idle times (nanoseconds since boot) for physical CPUs specified in the
- * @cpumap_bitmap with range [0..@cpumap_nr_cpus-1]. The @idletime array is
- * indexed by CPU number; only entries with the corresponding @cpumap_bitmap
- * bit set are written to. On return, @cpumap_bitmap is modified so that any
- * non-existent CPUs are cleared. Such CPUs have their @idletime array entry
- * cleared.
- */
-#define XENPF_getidletime 53
-struct xenpf_getidletime {
- /* IN/OUT variables */
- /* IN: CPUs to interrogate; OUT: subset of IN which are present */
- XEN_GUEST_HANDLE(uint8) cpumap_bitmap;
- /* IN variables */
- /* Size of cpumap bitmap. */
- uint32_t cpumap_nr_cpus;
- /* Must be indexable for every cpu in cpumap_bitmap. */
- XEN_GUEST_HANDLE(uint64) idletime;
- /* OUT variables */
- /* System time when the idletime snapshots were taken. */
- uint64_t now;
-};
-typedef struct xenpf_getidletime xenpf_getidletime_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
-
-#define XENPF_set_processor_pminfo 54
-
-/* ability bits */
-#define XEN_PROCESSOR_PM_CX 1
-#define XEN_PROCESSOR_PM_PX 2
-#define XEN_PROCESSOR_PM_TX 4
-
-/* cmd type */
-#define XEN_PM_CX 0
-#define XEN_PM_PX 1
-#define XEN_PM_TX 2
-#define XEN_PM_PDC 3
-
-/* Px sub info type */
-#define XEN_PX_PCT 1
-#define XEN_PX_PSS 2
-#define XEN_PX_PPC 4
-#define XEN_PX_PSD 8
-
-struct xen_power_register {
- uint32_t space_id;
- uint32_t bit_width;
- uint32_t bit_offset;
- uint32_t access_size;
- uint64_t address;
-};
-
-struct xen_processor_csd {
- uint32_t domain; /* domain number of one dependent group */
- uint32_t coord_type; /* coordination type */
- uint32_t num; /* number of processors in same domain */
-};
-typedef struct xen_processor_csd xen_processor_csd_t;
-DEFINE_XEN_GUEST_HANDLE(xen_processor_csd_t);
-
-struct xen_processor_cx {
- struct xen_power_register reg; /* GAS for Cx trigger register */
- uint8_t type; /* cstate value, c0: 0, c1: 1, ... */
- uint32_t latency; /* worst latency (ms) to enter/exit this cstate */
- uint32_t power; /* average power consumption(mW) */
- uint32_t dpcnt; /* number of dependency entries */
- XEN_GUEST_HANDLE(xen_processor_csd_t) dp; /* NULL if no dependency */
-};
-typedef struct xen_processor_cx xen_processor_cx_t;
-DEFINE_XEN_GUEST_HANDLE(xen_processor_cx_t);
-
-struct xen_processor_flags {
- uint32_t bm_control:1;
- uint32_t bm_check:1;
- uint32_t has_cst:1;
- uint32_t power_setup_done:1;
- uint32_t bm_rld_set:1;
-};
-
-struct xen_processor_power {
- uint32_t count; /* number of C state entries in array below */
- struct xen_processor_flags flags; /* global flags of this processor */
- XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
-};
-
-struct xen_pct_register {
- uint8_t descriptor;
- uint16_t length;
- uint8_t space_id;
- uint8_t bit_width;
- uint8_t bit_offset;
- uint8_t reserved;
- uint64_t address;
-};
-
-struct xen_processor_px {
- uint64_t core_frequency; /* megahertz */
- uint64_t power; /* milliWatts */
- uint64_t transition_latency; /* microseconds */
- uint64_t bus_master_latency; /* microseconds */
- uint64_t control; /* control value */
- uint64_t status; /* success indicator */
-};
-typedef struct xen_processor_px xen_processor_px_t;
-DEFINE_XEN_GUEST_HANDLE(xen_processor_px_t);
-
-struct xen_psd_package {
- uint64_t num_entries;
- uint64_t revision;
- uint64_t domain;
- uint64_t coord_type;
- uint64_t num_processors;
-};
-
-struct xen_processor_performance {
- uint32_t flags; /* flag for Px sub info type */
- uint32_t platform_limit; /* Platform limitation on freq usage */
- struct xen_pct_register control_register;
- struct xen_pct_register status_register;
- uint32_t state_count; /* total available performance states */
- XEN_GUEST_HANDLE(xen_processor_px_t) states;
- struct xen_psd_package domain_info;
- uint32_t shared_type; /* coordination type of this processor */
-};
-typedef struct xen_processor_performance xen_processor_performance_t;
-DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
-
-struct xenpf_set_processor_pminfo {
- /* IN variables */
- uint32_t id; /* ACPI CPU ID */
- uint32_t type; /* {XEN_PM_CX, XEN_PM_PX} */
- union {
- struct xen_processor_power power;/* Cx: _CST/_CSD */
- struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */
- XEN_GUEST_HANDLE(uint32) pdc; /* _PDC */
- } u;
-};
-typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
-
-#define XENPF_get_cpuinfo 55
-struct xenpf_pcpuinfo {
- /* IN */
- uint32_t xen_cpuid;
- /* OUT */
- /* The maxium cpu_id that is present */
- uint32_t max_present;
-#define XEN_PCPU_FLAGS_ONLINE 1
- /* Correponding xen_cpuid is not present*/
-#define XEN_PCPU_FLAGS_INVALID 2
- uint32_t flags;
- uint32_t apic_id;
- uint32_t acpi_id;
-};
-typedef struct xenpf_pcpuinfo xenpf_pcpuinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_pcpuinfo_t);
-
-#define XENPF_get_cpu_version 48
-struct xenpf_pcpu_version {
- /* IN */
- uint32_t xen_cpuid;
- /* OUT */
- /* The maxium cpu_id that is present */
- uint32_t max_present;
- char vendor_id[12];
- uint32_t family;
- uint32_t model;
- uint32_t stepping;
-};
-typedef struct xenpf_pcpu_version xenpf_pcpu_version_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_pcpu_version_t);
-
-#define XENPF_cpu_online 56
-#define XENPF_cpu_offline 57
-struct xenpf_cpu_ol
-{
- uint32_t cpuid;
-};
-typedef struct xenpf_cpu_ol xenpf_cpu_ol_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_cpu_ol_t);
-
-#define XENPF_cpu_hotadd 58
-struct xenpf_cpu_hotadd
-{
- uint32_t apic_id;
- uint32_t acpi_id;
- uint32_t pxm;
-};
-
-#define XENPF_mem_hotadd 59
-struct xenpf_mem_hotadd
-{
- uint64_t spfn;
- uint64_t epfn;
- uint32_t pxm;
- uint32_t flags;
-};
-
-#define XENPF_core_parking 60
-
-#define XEN_CORE_PARKING_SET 1
-#define XEN_CORE_PARKING_GET 2
-struct xenpf_core_parking {
- /* IN variables */
- uint32_t type;
- /* IN variables: set cpu nums expected to be idled */
- /* OUT variables: get cpu nums actually be idled */
- uint32_t idle_nums;
-};
-typedef struct xenpf_core_parking xenpf_core_parking_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
-
-/*
- * Access generic platform resources(e.g., accessing MSR, port I/O, etc)
- * in unified way. Batch resource operations in one call are supported and
- * they are always non-preemptible and executed in their original order.
- * The batch itself returns a negative integer for general errors, or a
- * non-negative integer for the number of successful operations. For the latter
- * case, the @ret in the failed entry (if any) indicates the exact error.
- */
-#define XENPF_resource_op 61
-
-#define XEN_RESOURCE_OP_MSR_READ 0
-#define XEN_RESOURCE_OP_MSR_WRITE 1
-
-struct xenpf_resource_entry {
- union {
- uint32_t cmd; /* IN: XEN_RESOURCE_OP_* */
- int32_t ret; /* OUT: return value for failed entry */
- } u;
- uint32_t rsvd; /* IN: padding and must be zero */
- uint64_t idx; /* IN: resource address to access */
- uint64_t val; /* IN/OUT: resource value to set/get */
-};
-typedef struct xenpf_resource_entry xenpf_resource_entry_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_resource_entry_t);
-
-struct xenpf_resource_op {
- uint32_t nr_entries; /* number of resource entry */
- uint32_t cpu; /* which cpu to run */
- XEN_GUEST_HANDLE(xenpf_resource_entry_t) entries;
-};
-typedef struct xenpf_resource_op xenpf_resource_op_t;
-DEFINE_XEN_GUEST_HANDLE(xenpf_resource_op_t);
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_platform_op(const struct xen_platform_op*);
- */
-struct xen_platform_op {
- uint32_t cmd;
- uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
- union {
- struct xenpf_settime settime;
- struct xenpf_add_memtype add_memtype;
- struct xenpf_del_memtype del_memtype;
- struct xenpf_read_memtype read_memtype;
- struct xenpf_microcode_update microcode;
- struct xenpf_platform_quirk platform_quirk;
- struct xenpf_efi_runtime_call efi_runtime_call;
- struct xenpf_firmware_info firmware_info;
- struct xenpf_enter_acpi_sleep enter_acpi_sleep;
- struct xenpf_change_freq change_freq;
- struct xenpf_getidletime getidletime;
- struct xenpf_set_processor_pminfo set_pminfo;
- struct xenpf_pcpuinfo pcpu_info;
- struct xenpf_pcpu_version pcpu_version;
- struct xenpf_cpu_ol cpu_ol;
- struct xenpf_cpu_hotadd cpu_add;
- struct xenpf_mem_hotadd mem_add;
- struct xenpf_core_parking core_parking;
- struct xenpf_resource_op resource_op;
- uint8_t pad[128];
- } u;
-};
-typedef struct xen_platform_op xen_platform_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_platform_op_t);
-
-#endif /* __XEN_PUBLIC_PLATFORM_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * sched.h
- *
- * Scheduler state interactions
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_SCHED_H__
-#define __XEN_PUBLIC_SCHED_H__
-
-#include "event_channel.h"
-
-/*
- * `incontents 150 sched Guest Scheduler Operations
- *
- * The SCHEDOP interface provides mechanisms for a guest to interact
- * with the scheduler, including yield, blocking and shutting itself
- * down.
- */
-
-/*
- * The prototype for this hypercall is:
- * ` long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...)
- *
- * @cmd == SCHEDOP_??? (scheduler operation).
- * @arg == Operation-specific extra argument(s), as described below.
- * ... == Additional Operation-specific extra arguments, described below.
- *
- * Versions of Xen prior to 3.0.2 provided only the following legacy version
- * of this hypercall, supporting only the commands yield, block and shutdown:
- * long sched_op(int cmd, unsigned long arg)
- * @cmd == SCHEDOP_??? (scheduler operation).
- * @arg == 0 (SCHEDOP_yield and SCHEDOP_block)
- * == SHUTDOWN_* code (SCHEDOP_shutdown)
- *
- * This legacy version is available to new guests as:
- * ` long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg)
- */
-
-/* ` enum sched_op { // SCHEDOP_* => struct sched_* */
-/*
- * Voluntarily yield the CPU.
- * @arg == NULL.
- */
-#define SCHEDOP_yield 0
-
-/*
- * Block execution of this VCPU until an event is received for processing.
- * If called with event upcalls masked, this operation will atomically
- * reenable event delivery and check for pending events before blocking the
- * VCPU. This avoids a "wakeup waiting" race.
- * @arg == NULL.
- */
-#define SCHEDOP_block 1
-
-/*
- * Halt execution of this domain (all VCPUs) and notify the system controller.
- * @arg == pointer to sched_shutdown_t structure.
- *
- * If the sched_shutdown_t reason is SHUTDOWN_suspend then
- * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
- * of the guest's start info page. RDX/EDX is the third hypercall
- * argument.
- *
- * In addition, which reason is SHUTDOWN_suspend this hypercall
- * returns 1 if suspend was cancelled or the domain was merely
- * checkpointed, and 0 if it is resuming in a new domain.
- */
-#define SCHEDOP_shutdown 2
-
-/*
- * Poll a set of event-channel ports. Return when one or more are pending. An
- * optional timeout may be specified.
- * @arg == pointer to sched_poll_t structure.
- */
-#define SCHEDOP_poll 3
-
-/*
- * Declare a shutdown for another domain. The main use of this function is
- * in interpreting shutdown requests and reasons for fully-virtualized
- * domains. A para-virtualized domain may use SCHEDOP_shutdown directly.
- * @arg == pointer to sched_remote_shutdown_t structure.
- */
-#define SCHEDOP_remote_shutdown 4
-
-/*
- * Latch a shutdown code, so that when the domain later shuts down it
- * reports this code to the control tools.
- * @arg == sched_shutdown_t, as for SCHEDOP_shutdown.
- */
-#define SCHEDOP_shutdown_code 5
-
-/*
- * Setup, poke and destroy a domain watchdog timer.
- * @arg == pointer to sched_watchdog_t structure.
- * With id == 0, setup a domain watchdog timer to cause domain shutdown
- * after timeout, returns watchdog id.
- * With id != 0 and timeout == 0, destroy domain watchdog timer.
- * With id != 0 and timeout != 0, poke watchdog timer and set new timeout.
- */
-#define SCHEDOP_watchdog 6
-/* ` } */
-
-struct sched_shutdown {
- unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
-};
-typedef struct sched_shutdown sched_shutdown_t;
-DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);
-
-struct sched_poll {
- XEN_GUEST_HANDLE(evtchn_port_t) ports;
- unsigned int nr_ports;
- uint64_t timeout;
-};
-typedef struct sched_poll sched_poll_t;
-DEFINE_XEN_GUEST_HANDLE(sched_poll_t);
-
-struct sched_remote_shutdown {
- domid_t domain_id; /* Remote domain ID */
- unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
-};
-typedef struct sched_remote_shutdown sched_remote_shutdown_t;
-DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);
-
-struct sched_watchdog {
- uint32_t id; /* watchdog ID */
- uint32_t timeout; /* timeout */
-};
-typedef struct sched_watchdog sched_watchdog_t;
-DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t);
-
-/*
- * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
- * software to determine the appropriate action. For the most part, Xen does
- * not care about the shutdown code.
- */
-/* ` enum sched_shutdown_reason { */
-#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
-#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
-#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
-#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
-#define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */
-#define SHUTDOWN_MAX 4 /* Maximum valid shutdown reason. */
-/* ` } */
-
-#endif /* __XEN_PUBLIC_SCHED_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * sysctl.h
- *
- * System management operations. For use by node control stack.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2002-2006, K Fraser
- */
-
-#ifndef __XEN_PUBLIC_SYSCTL_H__
-#define __XEN_PUBLIC_SYSCTL_H__
-
-#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
-#error "sysctl operations are intended for use by node control tools only"
-#endif
-
-#include "xen.h"
-#include "domctl.h"
-
-#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000B
-
-/*
- * Read console content from Xen buffer ring.
- */
-/* XEN_SYSCTL_readconsole */
-struct xen_sysctl_readconsole {
- /* IN: Non-zero -> clear after reading. */
- uint8_t clear;
- /* IN: Non-zero -> start index specified by @index field. */
- uint8_t incremental;
- uint8_t pad0, pad1;
- /*
- * IN: Start index for consuming from ring buffer (if @incremental);
- * OUT: End index after consuming from ring buffer.
- */
- uint32_t index;
- /* IN: Virtual address to write console data. */
- XEN_GUEST_HANDLE_64(char) buffer;
- /* IN: Size of buffer; OUT: Bytes written to buffer. */
- uint32_t count;
-};
-typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t);
-
-/* Get trace buffers machine base address */
-/* XEN_SYSCTL_tbuf_op */
-struct xen_sysctl_tbuf_op {
- /* IN variables */
-#define XEN_SYSCTL_TBUFOP_get_info 0
-#define XEN_SYSCTL_TBUFOP_set_cpu_mask 1
-#define XEN_SYSCTL_TBUFOP_set_evt_mask 2
-#define XEN_SYSCTL_TBUFOP_set_size 3
-#define XEN_SYSCTL_TBUFOP_enable 4
-#define XEN_SYSCTL_TBUFOP_disable 5
- uint32_t cmd;
- /* IN/OUT variables */
- struct xenctl_bitmap cpu_mask;
- uint32_t evt_mask;
- /* OUT variables */
- uint64_aligned_t buffer_mfn;
- uint32_t size; /* Also an IN variable! */
-};
-typedef struct xen_sysctl_tbuf_op xen_sysctl_tbuf_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_op_t);
-
-/*
- * Get physical information about the host machine
- */
-/* XEN_SYSCTL_physinfo */
- /* (x86) The platform supports HVM guests. */
-#define _XEN_SYSCTL_PHYSCAP_hvm 0
-#define XEN_SYSCTL_PHYSCAP_hvm (1u<<_XEN_SYSCTL_PHYSCAP_hvm)
- /* (x86) The platform supports HVM-guest direct access to I/O devices. */
-#define _XEN_SYSCTL_PHYSCAP_hvm_directio 1
-#define XEN_SYSCTL_PHYSCAP_hvm_directio (1u<<_XEN_SYSCTL_PHYSCAP_hvm_directio)
-struct xen_sysctl_physinfo {
- uint32_t threads_per_core;
- uint32_t cores_per_socket;
- uint32_t nr_cpus; /* # CPUs currently online */
- uint32_t max_cpu_id; /* Largest possible CPU ID on this host */
- uint32_t nr_nodes; /* # nodes currently online */
- uint32_t max_node_id; /* Largest possible node ID on this host */
- uint32_t cpu_khz;
- uint64_aligned_t total_pages;
- uint64_aligned_t free_pages;
- uint64_aligned_t scrub_pages;
- uint64_aligned_t outstanding_pages;
- uint32_t hw_cap[8];
-
- /* XEN_SYSCTL_PHYSCAP_??? */
- uint32_t capabilities;
-};
-typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
-
-/*
- * Get the ID of the current scheduler.
- */
-/* XEN_SYSCTL_sched_id */
-struct xen_sysctl_sched_id {
- /* OUT variable */
- uint32_t sched_id;
-};
-typedef struct xen_sysctl_sched_id xen_sysctl_sched_id_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_sched_id_t);
-
-/* Interface for controlling Xen software performance counters. */
-/* XEN_SYSCTL_perfc_op */
-/* Sub-operations: */
-#define XEN_SYSCTL_PERFCOP_reset 1 /* Reset all counters to zero. */
-#define XEN_SYSCTL_PERFCOP_query 2 /* Get perfctr information. */
-struct xen_sysctl_perfc_desc {
- char name[80]; /* name of perf counter */
- uint32_t nr_vals; /* number of values for this counter */
-};
-typedef struct xen_sysctl_perfc_desc xen_sysctl_perfc_desc_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t);
-typedef uint32_t xen_sysctl_perfc_val_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t);
-
-struct xen_sysctl_perfc_op {
- /* IN variables. */
- uint32_t cmd; /* XEN_SYSCTL_PERFCOP_??? */
- /* OUT variables. */
- uint32_t nr_counters; /* number of counters description */
- uint32_t nr_vals; /* number of values */
- /* counter information (or NULL) */
- XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc;
- /* counter values (or NULL) */
- XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val;
-};
-typedef struct xen_sysctl_perfc_op xen_sysctl_perfc_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_op_t);
-
-/* XEN_SYSCTL_getdomaininfolist */
-struct xen_sysctl_getdomaininfolist {
- /* IN variables. */
- domid_t first_domain;
- uint32_t max_domains;
- XEN_GUEST_HANDLE_64(xen_domctl_getdomaininfo_t) buffer;
- /* OUT variables. */
- uint32_t num_domains;
-};
-typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
-
-/* Inject debug keys into Xen. */
-/* XEN_SYSCTL_debug_keys */
-struct xen_sysctl_debug_keys {
- /* IN variables. */
- XEN_GUEST_HANDLE_64(char) keys;
- uint32_t nr_keys;
-};
-typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t);
-
-/* Get physical CPU information. */
-/* XEN_SYSCTL_getcpuinfo */
-struct xen_sysctl_cpuinfo {
- uint64_aligned_t idletime;
-};
-typedef struct xen_sysctl_cpuinfo xen_sysctl_cpuinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpuinfo_t);
-struct xen_sysctl_getcpuinfo {
- /* IN variables. */
- uint32_t max_cpus;
- XEN_GUEST_HANDLE_64(xen_sysctl_cpuinfo_t) info;
- /* OUT variables. */
- uint32_t nr_cpus;
-};
-typedef struct xen_sysctl_getcpuinfo xen_sysctl_getcpuinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getcpuinfo_t);
-
-/* XEN_SYSCTL_availheap */
-struct xen_sysctl_availheap {
- /* IN variables. */
- uint32_t min_bitwidth; /* Smallest address width (zero if don't care). */
- uint32_t max_bitwidth; /* Largest address width (zero if don't care). */
- int32_t node; /* NUMA node of interest (-1 for all nodes). */
- /* OUT variables. */
- uint64_aligned_t avail_bytes;/* Bytes available in the specified region. */
-};
-typedef struct xen_sysctl_availheap xen_sysctl_availheap_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t);
-
-/* XEN_SYSCTL_get_pmstat */
-struct pm_px_val {
- uint64_aligned_t freq; /* Px core frequency */
- uint64_aligned_t residency; /* Px residency time */
- uint64_aligned_t count; /* Px transition count */
-};
-typedef struct pm_px_val pm_px_val_t;
-DEFINE_XEN_GUEST_HANDLE(pm_px_val_t);
-
-struct pm_px_stat {
- uint8_t total; /* total Px states */
- uint8_t usable; /* usable Px states */
- uint8_t last; /* last Px state */
- uint8_t cur; /* current Px state */
- XEN_GUEST_HANDLE_64(uint64) trans_pt; /* Px transition table */
- XEN_GUEST_HANDLE_64(pm_px_val_t) pt;
-};
-typedef struct pm_px_stat pm_px_stat_t;
-DEFINE_XEN_GUEST_HANDLE(pm_px_stat_t);
-
-struct pm_cx_stat {
- uint32_t nr; /* entry nr in triggers & residencies, including C0 */
- uint32_t last; /* last Cx state */
- uint64_aligned_t idle_time; /* idle time from boot */
- XEN_GUEST_HANDLE_64(uint64) triggers; /* Cx trigger counts */
- XEN_GUEST_HANDLE_64(uint64) residencies; /* Cx residencies */
- uint32_t nr_pc; /* entry nr in pc[] */
- uint32_t nr_cc; /* entry nr in cc[] */
- /*
- * These two arrays may (and generally will) have unused slots; slots not
- * having a corresponding hardware register will not be written by the
- * hypervisor. It is therefore up to the caller to put a suitable sentinel
- * into all slots before invoking the function.
- * Indexing is 1-biased (PC1/CC1 being at index 0).
- */
- XEN_GUEST_HANDLE_64(uint64) pc;
- XEN_GUEST_HANDLE_64(uint64) cc;
-};
-
-struct xen_sysctl_get_pmstat {
-#define PMSTAT_CATEGORY_MASK 0xf0
-#define PMSTAT_PX 0x10
-#define PMSTAT_CX 0x20
-#define PMSTAT_get_max_px (PMSTAT_PX | 0x1)
-#define PMSTAT_get_pxstat (PMSTAT_PX | 0x2)
-#define PMSTAT_reset_pxstat (PMSTAT_PX | 0x3)
-#define PMSTAT_get_max_cx (PMSTAT_CX | 0x1)
-#define PMSTAT_get_cxstat (PMSTAT_CX | 0x2)
-#define PMSTAT_reset_cxstat (PMSTAT_CX | 0x3)
- uint32_t type;
- uint32_t cpuid;
- union {
- struct pm_px_stat getpx;
- struct pm_cx_stat getcx;
- /* other struct for tx, etc */
- } u;
-};
-typedef struct xen_sysctl_get_pmstat xen_sysctl_get_pmstat_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_get_pmstat_t);
-
-/* XEN_SYSCTL_cpu_hotplug */
-struct xen_sysctl_cpu_hotplug {
- /* IN variables */
- uint32_t cpu; /* Physical cpu. */
-#define XEN_SYSCTL_CPU_HOTPLUG_ONLINE 0
-#define XEN_SYSCTL_CPU_HOTPLUG_OFFLINE 1
- uint32_t op; /* hotplug opcode */
-};
-typedef struct xen_sysctl_cpu_hotplug xen_sysctl_cpu_hotplug_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpu_hotplug_t);
-
-/*
- * Get/set xen power management, include
- * 1. cpufreq governors and related parameters
- */
-/* XEN_SYSCTL_pm_op */
-struct xen_userspace {
- uint32_t scaling_setspeed;
-};
-typedef struct xen_userspace xen_userspace_t;
-
-struct xen_ondemand {
- uint32_t sampling_rate_max;
- uint32_t sampling_rate_min;
-
- uint32_t sampling_rate;
- uint32_t up_threshold;
-};
-typedef struct xen_ondemand xen_ondemand_t;
-
-/*
- * cpufreq para name of this structure named
- * same as sysfs file name of native linux
- */
-#define CPUFREQ_NAME_LEN 16
-struct xen_get_cpufreq_para {
- /* IN/OUT variable */
- uint32_t cpu_num;
- uint32_t freq_num;
- uint32_t gov_num;
-
- /* for all governors */
- /* OUT variable */
- XEN_GUEST_HANDLE_64(uint32) affected_cpus;
- XEN_GUEST_HANDLE_64(uint32) scaling_available_frequencies;
- XEN_GUEST_HANDLE_64(char) scaling_available_governors;
- char scaling_driver[CPUFREQ_NAME_LEN];
-
- uint32_t cpuinfo_cur_freq;
- uint32_t cpuinfo_max_freq;
- uint32_t cpuinfo_min_freq;
- uint32_t scaling_cur_freq;
-
- char scaling_governor[CPUFREQ_NAME_LEN];
- uint32_t scaling_max_freq;
- uint32_t scaling_min_freq;
-
- /* for specific governor */
- union {
- struct xen_userspace userspace;
- struct xen_ondemand ondemand;
- } u;
-
- int32_t turbo_enabled;
-};
-
-struct xen_set_cpufreq_gov {
- char scaling_governor[CPUFREQ_NAME_LEN];
-};
-
-struct xen_set_cpufreq_para {
- #define SCALING_MAX_FREQ 1
- #define SCALING_MIN_FREQ 2
- #define SCALING_SETSPEED 3
- #define SAMPLING_RATE 4
- #define UP_THRESHOLD 5
-
- uint32_t ctrl_type;
- uint32_t ctrl_value;
-};
-
-struct xen_sysctl_pm_op {
- #define PM_PARA_CATEGORY_MASK 0xf0
- #define CPUFREQ_PARA 0x10
-
- /* cpufreq command type */
- #define GET_CPUFREQ_PARA (CPUFREQ_PARA | 0x01)
- #define SET_CPUFREQ_GOV (CPUFREQ_PARA | 0x02)
- #define SET_CPUFREQ_PARA (CPUFREQ_PARA | 0x03)
- #define GET_CPUFREQ_AVGFREQ (CPUFREQ_PARA | 0x04)
-
- /* set/reset scheduler power saving option */
- #define XEN_SYSCTL_pm_op_set_sched_opt_smt 0x21
-
- /* cpuidle max_cstate access command */
- #define XEN_SYSCTL_pm_op_get_max_cstate 0x22
- #define XEN_SYSCTL_pm_op_set_max_cstate 0x23
-
- /* set scheduler migration cost value */
- #define XEN_SYSCTL_pm_op_set_vcpu_migration_delay 0x24
- #define XEN_SYSCTL_pm_op_get_vcpu_migration_delay 0x25
-
- /* enable/disable turbo mode when in dbs governor */
- #define XEN_SYSCTL_pm_op_enable_turbo 0x26
- #define XEN_SYSCTL_pm_op_disable_turbo 0x27
-
- uint32_t cmd;
- uint32_t cpuid;
- union {
- struct xen_get_cpufreq_para get_para;
- struct xen_set_cpufreq_gov set_gov;
- struct xen_set_cpufreq_para set_para;
- uint64_aligned_t get_avgfreq;
- uint32_t set_sched_opt_smt;
- uint32_t get_max_cstate;
- uint32_t set_max_cstate;
- uint32_t get_vcpu_migration_delay;
- uint32_t set_vcpu_migration_delay;
- } u;
-};
-
-/* XEN_SYSCTL_page_offline_op */
-struct xen_sysctl_page_offline_op {
- /* IN: range of page to be offlined */
-#define sysctl_page_offline 1
-#define sysctl_page_online 2
-#define sysctl_query_page_offline 3
- uint32_t cmd;
- uint32_t start;
- uint32_t end;
- /* OUT: result of page offline request */
- /*
- * bit 0~15: result flags
- * bit 16~31: owner
- */
- XEN_GUEST_HANDLE(uint32) status;
-};
-
-#define PG_OFFLINE_STATUS_MASK (0xFFUL)
-
-/* The result is invalid, i.e. HV does not handle it */
-#define PG_OFFLINE_INVALID (0x1UL << 0)
-
-#define PG_OFFLINE_OFFLINED (0x1UL << 1)
-#define PG_OFFLINE_PENDING (0x1UL << 2)
-#define PG_OFFLINE_FAILED (0x1UL << 3)
-#define PG_OFFLINE_AGAIN (0x1UL << 4)
-
-#define PG_ONLINE_FAILED PG_OFFLINE_FAILED
-#define PG_ONLINE_ONLINED PG_OFFLINE_OFFLINED
-
-#define PG_OFFLINE_STATUS_OFFLINED (0x1UL << 1)
-#define PG_OFFLINE_STATUS_ONLINE (0x1UL << 2)
-#define PG_OFFLINE_STATUS_OFFLINE_PENDING (0x1UL << 3)
-#define PG_OFFLINE_STATUS_BROKEN (0x1UL << 4)
-
-#define PG_OFFLINE_MISC_MASK (0xFFUL << 4)
-
-/* valid when PG_OFFLINE_FAILED or PG_OFFLINE_PENDING */
-#define PG_OFFLINE_XENPAGE (0x1UL << 8)
-#define PG_OFFLINE_DOM0PAGE (0x1UL << 9)
-#define PG_OFFLINE_ANONYMOUS (0x1UL << 10)
-#define PG_OFFLINE_NOT_CONV_RAM (0x1UL << 11)
-#define PG_OFFLINE_OWNED (0x1UL << 12)
-
-#define PG_OFFLINE_BROKEN (0x1UL << 13)
-#define PG_ONLINE_BROKEN PG_OFFLINE_BROKEN
-
-#define PG_OFFLINE_OWNER_SHIFT 16
-
-/* XEN_SYSCTL_lockprof_op */
-/* Sub-operations: */
-#define XEN_SYSCTL_LOCKPROF_reset 1 /* Reset all profile data to zero. */
-#define XEN_SYSCTL_LOCKPROF_query 2 /* Get lock profile information. */
-/* Record-type: */
-#define LOCKPROF_TYPE_GLOBAL 0 /* global lock, idx meaningless */
-#define LOCKPROF_TYPE_PERDOM 1 /* per-domain lock, idx is domid */
-#define LOCKPROF_TYPE_N 2 /* number of types */
-struct xen_sysctl_lockprof_data {
- char name[40]; /* lock name (may include up to 2 %d specifiers) */
- int32_t type; /* LOCKPROF_TYPE_??? */
- int32_t idx; /* index (e.g. domain id) */
- uint64_aligned_t lock_cnt; /* # of locking succeeded */
- uint64_aligned_t block_cnt; /* # of wait for lock */
- uint64_aligned_t lock_time; /* nsecs lock held */
- uint64_aligned_t block_time; /* nsecs waited for lock */
-};
-typedef struct xen_sysctl_lockprof_data xen_sysctl_lockprof_data_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_data_t);
-struct xen_sysctl_lockprof_op {
- /* IN variables. */
- uint32_t cmd; /* XEN_SYSCTL_LOCKPROF_??? */
- uint32_t max_elem; /* size of output buffer */
- /* OUT variables (query only). */
- uint32_t nr_elem; /* number of elements available */
- uint64_aligned_t time; /* nsecs of profile measurement */
- /* profile information (or NULL) */
- XEN_GUEST_HANDLE_64(xen_sysctl_lockprof_data_t) data;
-};
-typedef struct xen_sysctl_lockprof_op xen_sysctl_lockprof_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_op_t);
-
-/* XEN_SYSCTL_topologyinfo */
-#define INVALID_TOPOLOGY_ID (~0U)
-struct xen_sysctl_topologyinfo {
- /*
- * IN: maximum addressable entry in the caller-provided arrays.
- * OUT: largest cpu identifier in the system.
- * If OUT is greater than IN then the arrays are truncated!
- * If OUT is leass than IN then the array tails are not written by sysctl.
- */
- uint32_t max_cpu_index;
-
- /*
- * If not NULL, these arrays are filled with core/socket/node identifier
- * for each cpu.
- * If a cpu has no core/socket/node information (e.g., cpu not present)
- * then the sentinel value ~0u is written to each array.
- * The number of array elements written by the sysctl is:
- * min(@max_cpu_index_IN,@max_cpu_index_OUT)+1
- */
- XEN_GUEST_HANDLE_64(uint32) cpu_to_core;
- XEN_GUEST_HANDLE_64(uint32) cpu_to_socket;
- XEN_GUEST_HANDLE_64(uint32) cpu_to_node;
-};
-typedef struct xen_sysctl_topologyinfo xen_sysctl_topologyinfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_topologyinfo_t);
-
-/* XEN_SYSCTL_numainfo */
-#define INVALID_NUMAINFO_ID (~0U)
-struct xen_sysctl_numainfo {
- /*
- * IN: maximum addressable entry in the caller-provided arrays.
- * OUT: largest node identifier in the system.
- * If OUT is greater than IN then the arrays are truncated!
- */
- uint32_t max_node_index;
-
- /* NB. Entries are 0 if node is not present. */
- XEN_GUEST_HANDLE_64(uint64) node_to_memsize;
- XEN_GUEST_HANDLE_64(uint64) node_to_memfree;
-
- /*
- * Array, of size (max_node_index+1)^2, listing memory access distances
- * between nodes. If an entry has no node distance information (e.g., node
- * not present) then the value ~0u is written.
- *
- * Note that the array rows must be indexed by multiplying by the minimum
- * of the caller-provided max_node_index and the returned value of
- * max_node_index. That is, if the largest node index in the system is
- * smaller than the caller can handle, a smaller 2-d array is constructed
- * within the space provided by the caller. When this occurs, trailing
- * space provided by the caller is not modified. If the largest node index
- * in the system is larger than the caller can handle, then a 2-d array of
- * the maximum size handleable by the caller is constructed.
- */
- XEN_GUEST_HANDLE_64(uint32) node_to_node_distance;
-};
-typedef struct xen_sysctl_numainfo xen_sysctl_numainfo_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_numainfo_t);
-
-/* XEN_SYSCTL_cpupool_op */
-#define XEN_SYSCTL_CPUPOOL_OP_CREATE 1 /* C */
-#define XEN_SYSCTL_CPUPOOL_OP_DESTROY 2 /* D */
-#define XEN_SYSCTL_CPUPOOL_OP_INFO 3 /* I */
-#define XEN_SYSCTL_CPUPOOL_OP_ADDCPU 4 /* A */
-#define XEN_SYSCTL_CPUPOOL_OP_RMCPU 5 /* R */
-#define XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN 6 /* M */
-#define XEN_SYSCTL_CPUPOOL_OP_FREEINFO 7 /* F */
-#define XEN_SYSCTL_CPUPOOL_PAR_ANY 0xFFFFFFFF
-struct xen_sysctl_cpupool_op {
- uint32_t op; /* IN */
- uint32_t cpupool_id; /* IN: CDIARM OUT: CI */
- uint32_t sched_id; /* IN: C OUT: I */
- uint32_t domid; /* IN: M */
- uint32_t cpu; /* IN: AR */
- uint32_t n_dom; /* OUT: I */
- struct xenctl_bitmap cpumap; /* OUT: IF */
-};
-typedef struct xen_sysctl_cpupool_op xen_sysctl_cpupool_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpupool_op_t);
-
-#define ARINC653_MAX_DOMAINS_PER_SCHEDULE 64
-/*
- * This structure is used to pass a new ARINC653 schedule from a
- * privileged domain (ie dom0) to Xen.
- */
-struct xen_sysctl_arinc653_schedule {
- /* major_frame holds the time for the new schedule's major frame
- * in nanoseconds. */
- uint64_aligned_t major_frame;
- /* num_sched_entries holds how many of the entries in the
- * sched_entries[] array are valid. */
- uint8_t num_sched_entries;
- /* The sched_entries array holds the actual schedule entries. */
- struct {
- /* dom_handle must match a domain's UUID */
- xen_domain_handle_t dom_handle;
- /* If a domain has multiple VCPUs, vcpu_id specifies which one
- * this schedule entry applies to. It should be set to 0 if
- * there is only one VCPU for the domain. */
- unsigned int vcpu_id;
- /* runtime specifies the amount of time that should be allocated
- * to this VCPU per major frame. It is specified in nanoseconds */
- uint64_aligned_t runtime;
- } sched_entries[ARINC653_MAX_DOMAINS_PER_SCHEDULE];
-};
-typedef struct xen_sysctl_arinc653_schedule xen_sysctl_arinc653_schedule_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_arinc653_schedule_t);
-
-struct xen_sysctl_credit_schedule {
- /* Length of timeslice in milliseconds */
-#define XEN_SYSCTL_CSCHED_TSLICE_MAX 1000
-#define XEN_SYSCTL_CSCHED_TSLICE_MIN 1
- unsigned tslice_ms;
- /* Rate limit (minimum timeslice) in microseconds */
-#define XEN_SYSCTL_SCHED_RATELIMIT_MAX 500000
-#define XEN_SYSCTL_SCHED_RATELIMIT_MIN 100
- unsigned ratelimit_us;
-};
-typedef struct xen_sysctl_credit_schedule xen_sysctl_credit_schedule_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_credit_schedule_t);
-
-/* XEN_SYSCTL_scheduler_op */
-/* Set or get info? */
-#define XEN_SYSCTL_SCHEDOP_putinfo 0
-#define XEN_SYSCTL_SCHEDOP_getinfo 1
-struct xen_sysctl_scheduler_op {
- uint32_t cpupool_id; /* Cpupool whose scheduler is to be targetted. */
- uint32_t sched_id; /* XEN_SCHEDULER_* (domctl.h) */
- uint32_t cmd; /* XEN_SYSCTL_SCHEDOP_* */
- union {
- struct xen_sysctl_sched_arinc653 {
- XEN_GUEST_HANDLE_64(xen_sysctl_arinc653_schedule_t) schedule;
- } sched_arinc653;
- struct xen_sysctl_credit_schedule sched_credit;
- } u;
-};
-typedef struct xen_sysctl_scheduler_op xen_sysctl_scheduler_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_scheduler_op_t);
-
-/* XEN_SYSCTL_coverage_op */
-/*
- * Get total size of information, to help allocate
- * the buffer. The pointer points to a 32 bit value.
- */
-#define XEN_SYSCTL_COVERAGE_get_total_size 0
-
-/*
- * Read coverage information in a single run
- * You must use a tool to split them.
- */
-#define XEN_SYSCTL_COVERAGE_read 1
-
-/*
- * Reset all the coverage counters to 0
- * No parameters.
- */
-#define XEN_SYSCTL_COVERAGE_reset 2
-
-/*
- * Like XEN_SYSCTL_COVERAGE_read but reset also
- * counters to 0 in a single call.
- */
-#define XEN_SYSCTL_COVERAGE_read_and_reset 3
-
-struct xen_sysctl_coverage_op {
- uint32_t cmd; /* XEN_SYSCTL_COVERAGE_* */
- union {
- uint32_t total_size; /* OUT */
- XEN_GUEST_HANDLE_64(uint8) raw_info; /* OUT */
- } u;
-};
-typedef struct xen_sysctl_coverage_op xen_sysctl_coverage_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_coverage_op_t);
-
-#define XEN_SYSCTL_PSR_CMT_get_total_rmid 0
-#define XEN_SYSCTL_PSR_CMT_get_l3_upscaling_factor 1
-/* The L3 cache size is returned in KB unit */
-#define XEN_SYSCTL_PSR_CMT_get_l3_cache_size 2
-#define XEN_SYSCTL_PSR_CMT_enabled 3
-#define XEN_SYSCTL_PSR_CMT_get_l3_event_mask 4
-struct xen_sysctl_psr_cmt_op {
- uint32_t cmd; /* IN: XEN_SYSCTL_PSR_CMT_* */
- uint32_t flags; /* padding variable, may be extended for future use */
- union {
- uint64_t data; /* OUT */
- struct {
- uint32_t cpu; /* IN */
- uint32_t rsvd;
- } l3_cache;
- } u;
-};
-typedef struct xen_sysctl_psr_cmt_op xen_sysctl_psr_cmt_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_psr_cmt_op_t);
-
-struct xen_sysctl {
- uint32_t cmd;
-#define XEN_SYSCTL_readconsole 1
-#define XEN_SYSCTL_tbuf_op 2
-#define XEN_SYSCTL_physinfo 3
-#define XEN_SYSCTL_sched_id 4
-#define XEN_SYSCTL_perfc_op 5
-#define XEN_SYSCTL_getdomaininfolist 6
-#define XEN_SYSCTL_debug_keys 7
-#define XEN_SYSCTL_getcpuinfo 8
-#define XEN_SYSCTL_availheap 9
-#define XEN_SYSCTL_get_pmstat 10
-#define XEN_SYSCTL_cpu_hotplug 11
-#define XEN_SYSCTL_pm_op 12
-#define XEN_SYSCTL_page_offline_op 14
-#define XEN_SYSCTL_lockprof_op 15
-#define XEN_SYSCTL_topologyinfo 16
-#define XEN_SYSCTL_numainfo 17
-#define XEN_SYSCTL_cpupool_op 18
-#define XEN_SYSCTL_scheduler_op 19
-#define XEN_SYSCTL_coverage_op 20
-#define XEN_SYSCTL_psr_cmt_op 21
- uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
- union {
- struct xen_sysctl_readconsole readconsole;
- struct xen_sysctl_tbuf_op tbuf_op;
- struct xen_sysctl_physinfo physinfo;
- struct xen_sysctl_topologyinfo topologyinfo;
- struct xen_sysctl_numainfo numainfo;
- struct xen_sysctl_sched_id sched_id;
- struct xen_sysctl_perfc_op perfc_op;
- struct xen_sysctl_getdomaininfolist getdomaininfolist;
- struct xen_sysctl_debug_keys debug_keys;
- struct xen_sysctl_getcpuinfo getcpuinfo;
- struct xen_sysctl_availheap availheap;
- struct xen_sysctl_get_pmstat get_pmstat;
- struct xen_sysctl_cpu_hotplug cpu_hotplug;
- struct xen_sysctl_pm_op pm_op;
- struct xen_sysctl_page_offline_op page_offline;
- struct xen_sysctl_lockprof_op lockprof_op;
- struct xen_sysctl_cpupool_op cpupool_op;
- struct xen_sysctl_scheduler_op scheduler_op;
- struct xen_sysctl_coverage_op coverage_op;
- struct xen_sysctl_psr_cmt_op psr_cmt_op;
- uint8_t pad[128];
- } u;
-};
-typedef struct xen_sysctl xen_sysctl_t;
-DEFINE_XEN_GUEST_HANDLE(xen_sysctl_t);
-
-#endif /* __XEN_PUBLIC_SYSCTL_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * tmem.h
- *
- * Guest OS interface to Xen Transcendent Memory.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __XEN_PUBLIC_TMEM_H__
-#define __XEN_PUBLIC_TMEM_H__
-
-#include "xen.h"
-
-/* version of ABI */
-#define TMEM_SPEC_VERSION 1
-
-/* Commands to HYPERVISOR_tmem_op() */
-#define TMEM_CONTROL 0
-#define TMEM_NEW_POOL 1
-#define TMEM_DESTROY_POOL 2
-#define TMEM_PUT_PAGE 4
-#define TMEM_GET_PAGE 5
-#define TMEM_FLUSH_PAGE 6
-#define TMEM_FLUSH_OBJECT 7
-#if __XEN_INTERFACE_VERSION__ < 0x00040400
-#define TMEM_NEW_PAGE 3
-#define TMEM_READ 8
-#define TMEM_WRITE 9
-#define TMEM_XCHG 10
-#endif
-
-/* Privileged commands to HYPERVISOR_tmem_op() */
-#define TMEM_AUTH 101
-#define TMEM_RESTORE_NEW 102
-
-/* Subops for HYPERVISOR_tmem_op(TMEM_CONTROL) */
-#define TMEMC_THAW 0
-#define TMEMC_FREEZE 1
-#define TMEMC_FLUSH 2
-#define TMEMC_DESTROY 3
-#define TMEMC_LIST 4
-#define TMEMC_SET_WEIGHT 5
-#define TMEMC_SET_CAP 6
-#define TMEMC_SET_COMPRESS 7
-#define TMEMC_QUERY_FREEABLE_MB 8
-#define TMEMC_SAVE_BEGIN 10
-#define TMEMC_SAVE_GET_VERSION 11
-#define TMEMC_SAVE_GET_MAXPOOLS 12
-#define TMEMC_SAVE_GET_CLIENT_WEIGHT 13
-#define TMEMC_SAVE_GET_CLIENT_CAP 14
-#define TMEMC_SAVE_GET_CLIENT_FLAGS 15
-#define TMEMC_SAVE_GET_POOL_FLAGS 16
-#define TMEMC_SAVE_GET_POOL_NPAGES 17
-#define TMEMC_SAVE_GET_POOL_UUID 18
-#define TMEMC_SAVE_GET_NEXT_PAGE 19
-#define TMEMC_SAVE_GET_NEXT_INV 20
-#define TMEMC_SAVE_END 21
-#define TMEMC_RESTORE_BEGIN 30
-#define TMEMC_RESTORE_PUT_PAGE 32
-#define TMEMC_RESTORE_FLUSH_PAGE 33
-
-/* Bits for HYPERVISOR_tmem_op(TMEM_NEW_POOL) */
-#define TMEM_POOL_PERSIST 1
-#define TMEM_POOL_SHARED 2
-#define TMEM_POOL_PRECOMPRESSED 4
-#define TMEM_POOL_PAGESIZE_SHIFT 4
-#define TMEM_POOL_PAGESIZE_MASK 0xf
-#define TMEM_POOL_VERSION_SHIFT 24
-#define TMEM_POOL_VERSION_MASK 0xff
-#define TMEM_POOL_RESERVED_BITS 0x00ffff00
-
-/* Bits for client flags (save/restore) */
-#define TMEM_CLIENT_COMPRESS 1
-#define TMEM_CLIENT_FROZEN 2
-
-/* Special errno values */
-#define EFROZEN 1000
-#define EEMPTY 1001
-
-
-#ifndef __ASSEMBLY__
-#if __XEN_INTERFACE_VERSION__ < 0x00040400
-typedef xen_pfn_t tmem_cli_mfn_t;
-#endif
-typedef XEN_GUEST_HANDLE(char) tmem_cli_va_t;
-struct tmem_op {
- uint32_t cmd;
- int32_t pool_id;
- union {
- struct {
- uint64_t uuid[2];
- uint32_t flags;
- uint32_t arg1;
- } creat; /* for cmd == TMEM_NEW_POOL, TMEM_AUTH, TMEM_RESTORE_NEW */
- struct {
- uint32_t subop;
- uint32_t cli_id;
- uint32_t arg1;
- uint32_t arg2;
- uint64_t oid[3];
- tmem_cli_va_t buf;
- } ctrl; /* for cmd == TMEM_CONTROL */
- struct {
-
- uint64_t oid[3];
- uint32_t index;
- uint32_t tmem_offset;
- uint32_t pfn_offset;
- uint32_t len;
- xen_pfn_t cmfn; /* client machine page frame */
- } gen; /* for all other cmd ("generic") */
- } u;
-};
-typedef struct tmem_op tmem_op_t;
-DEFINE_XEN_GUEST_HANDLE(tmem_op_t);
-
-struct tmem_handle {
- uint32_t pool_id;
- uint32_t index;
- uint64_t oid[3];
-};
-#endif
-
-#endif /* __XEN_PUBLIC_TMEM_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * include/public/trace.h
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Mark Williamson, (C) 2004 Intel Research Cambridge
- * Copyright (C) 2005 Bin Ren
- */
-
-#ifndef __XEN_PUBLIC_TRACE_H__
-#define __XEN_PUBLIC_TRACE_H__
-
-#define TRACE_EXTRA_MAX 7
-#define TRACE_EXTRA_SHIFT 28
-
-/* Trace classes */
-#define TRC_CLS_SHIFT 16
-#define TRC_GEN 0x0001f000 /* General trace */
-#define TRC_SCHED 0x0002f000 /* Xen Scheduler trace */
-#define TRC_DOM0OP 0x0004f000 /* Xen DOM0 operation trace */
-#define TRC_HVM 0x0008f000 /* Xen HVM trace */
-#define TRC_MEM 0x0010f000 /* Xen memory trace */
-#define TRC_PV 0x0020f000 /* Xen PV traces */
-#define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */
-#define TRC_HW 0x0080f000 /* Xen hardware-related traces */
-#define TRC_GUEST 0x0800f000 /* Guest-generated traces */
-#define TRC_ALL 0x0ffff000
-#define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff)
-#define TRC_HD_CYCLE_FLAG (1UL<<31)
-#define TRC_HD_INCLUDES_CYCLE_COUNT(x) ( !!( (x) & TRC_HD_CYCLE_FLAG ) )
-#define TRC_HD_EXTRA(x) (((x)>>TRACE_EXTRA_SHIFT)&TRACE_EXTRA_MAX)
-
-/* Trace subclasses */
-#define TRC_SUBCLS_SHIFT 12
-
-/* trace subclasses for SVM */
-#define TRC_HVM_ENTRYEXIT 0x00081000 /* VMENTRY and #VMEXIT */
-#define TRC_HVM_HANDLER 0x00082000 /* various HVM handlers */
-#define TRC_HVM_EMUL 0x00084000 /* emulated devices */
-
-#define TRC_SCHED_MIN 0x00021000 /* Just runstate changes */
-#define TRC_SCHED_CLASS 0x00022000 /* Scheduler-specific */
-#define TRC_SCHED_VERBOSE 0x00028000 /* More inclusive scheduling */
-
-/*
- * The highest 3 bits of the last 12 bits of TRC_SCHED_CLASS above are
- * reserved for encoding what scheduler produced the information. The
- * actual event is encoded in the last 9 bits.
- *
- * This means we have 8 scheduling IDs available (which means at most 8
- * schedulers generating events) and, in each scheduler, up to 512
- * different events.
- */
-#define TRC_SCHED_ID_BITS 3
-#define TRC_SCHED_ID_SHIFT (TRC_SUBCLS_SHIFT - TRC_SCHED_ID_BITS)
-#define TRC_SCHED_ID_MASK (((1UL<<TRC_SCHED_ID_BITS) - 1) << TRC_SCHED_ID_SHIFT)
-#define TRC_SCHED_EVT_MASK (~(TRC_SCHED_ID_MASK))
-
-/* Per-scheduler IDs, to identify scheduler specific events */
-#define TRC_SCHED_CSCHED 0
-#define TRC_SCHED_CSCHED2 1
-#define TRC_SCHED_SEDF 2
-#define TRC_SCHED_ARINC653 3
-#define TRC_SCHED_RTDS 4
-
-/* Per-scheduler tracing */
-#define TRC_SCHED_CLASS_EVT(_c, _e) \
- ( ( TRC_SCHED_CLASS | \
- ((TRC_SCHED_##_c << TRC_SCHED_ID_SHIFT) & TRC_SCHED_ID_MASK) ) + \
- (_e & TRC_SCHED_EVT_MASK) )
-
-/* Trace classes for Hardware */
-#define TRC_HW_PM 0x00801000 /* Power management traces */
-#define TRC_HW_IRQ 0x00802000 /* Traces relating to the handling of IRQs */
-
-/* Trace events per class */
-#define TRC_LOST_RECORDS (TRC_GEN + 1)
-#define TRC_TRACE_WRAP_BUFFER (TRC_GEN + 2)
-#define TRC_TRACE_CPU_CHANGE (TRC_GEN + 3)
-
-#define TRC_SCHED_RUNSTATE_CHANGE (TRC_SCHED_MIN + 1)
-#define TRC_SCHED_CONTINUE_RUNNING (TRC_SCHED_MIN + 2)
-#define TRC_SCHED_DOM_ADD (TRC_SCHED_VERBOSE + 1)
-#define TRC_SCHED_DOM_REM (TRC_SCHED_VERBOSE + 2)
-#define TRC_SCHED_SLEEP (TRC_SCHED_VERBOSE + 3)
-#define TRC_SCHED_WAKE (TRC_SCHED_VERBOSE + 4)
-#define TRC_SCHED_YIELD (TRC_SCHED_VERBOSE + 5)
-#define TRC_SCHED_BLOCK (TRC_SCHED_VERBOSE + 6)
-#define TRC_SCHED_SHUTDOWN (TRC_SCHED_VERBOSE + 7)
-#define TRC_SCHED_CTL (TRC_SCHED_VERBOSE + 8)
-#define TRC_SCHED_ADJDOM (TRC_SCHED_VERBOSE + 9)
-#define TRC_SCHED_SWITCH (TRC_SCHED_VERBOSE + 10)
-#define TRC_SCHED_S_TIMER_FN (TRC_SCHED_VERBOSE + 11)
-#define TRC_SCHED_T_TIMER_FN (TRC_SCHED_VERBOSE + 12)
-#define TRC_SCHED_DOM_TIMER_FN (TRC_SCHED_VERBOSE + 13)
-#define TRC_SCHED_SWITCH_INFPREV (TRC_SCHED_VERBOSE + 14)
-#define TRC_SCHED_SWITCH_INFNEXT (TRC_SCHED_VERBOSE + 15)
-#define TRC_SCHED_SHUTDOWN_CODE (TRC_SCHED_VERBOSE + 16)
-
-#define TRC_MEM_PAGE_GRANT_MAP (TRC_MEM + 1)
-#define TRC_MEM_PAGE_GRANT_UNMAP (TRC_MEM + 2)
-#define TRC_MEM_PAGE_GRANT_TRANSFER (TRC_MEM + 3)
-#define TRC_MEM_SET_P2M_ENTRY (TRC_MEM + 4)
-#define TRC_MEM_DECREASE_RESERVATION (TRC_MEM + 5)
-#define TRC_MEM_POD_POPULATE (TRC_MEM + 16)
-#define TRC_MEM_POD_ZERO_RECLAIM (TRC_MEM + 17)
-#define TRC_MEM_POD_SUPERPAGE_SPLINTER (TRC_MEM + 18)
-
-#define TRC_PV_ENTRY 0x00201000 /* Hypervisor entry points for PV guests. */
-#define TRC_PV_SUBCALL 0x00202000 /* Sub-call in a multicall hypercall */
-
-#define TRC_PV_HYPERCALL (TRC_PV_ENTRY + 1)
-#define TRC_PV_TRAP (TRC_PV_ENTRY + 3)
-#define TRC_PV_PAGE_FAULT (TRC_PV_ENTRY + 4)
-#define TRC_PV_FORCED_INVALID_OP (TRC_PV_ENTRY + 5)
-#define TRC_PV_EMULATE_PRIVOP (TRC_PV_ENTRY + 6)
-#define TRC_PV_EMULATE_4GB (TRC_PV_ENTRY + 7)
-#define TRC_PV_MATH_STATE_RESTORE (TRC_PV_ENTRY + 8)
-#define TRC_PV_PAGING_FIXUP (TRC_PV_ENTRY + 9)
-#define TRC_PV_GDT_LDT_MAPPING_FAULT (TRC_PV_ENTRY + 10)
-#define TRC_PV_PTWR_EMULATION (TRC_PV_ENTRY + 11)
-#define TRC_PV_PTWR_EMULATION_PAE (TRC_PV_ENTRY + 12)
-#define TRC_PV_HYPERCALL_V2 (TRC_PV_ENTRY + 13)
-#define TRC_PV_HYPERCALL_SUBCALL (TRC_PV_SUBCALL + 14)
-
-/*
- * TRC_PV_HYPERCALL_V2 format
- *
- * Only some of the hypercall argument are recorded. Bit fields A0 to
- * A5 in the first extra word are set if the argument is present and
- * the arguments themselves are packed sequentially in the following
- * words.
- *
- * The TRC_64_FLAG bit is not set for these events (even if there are
- * 64-bit arguments in the record).
- *
- * Word
- * 0 bit 31 30|29 28|27 26|25 24|23 22|21 20|19 ... 0
- * A5 |A4 |A3 |A2 |A1 |A0 |Hypercall op
- * 1 First 32 bit (or low word of first 64 bit) arg in record
- * 2 Second 32 bit (or high word of first 64 bit) arg in record
- * ...
- *
- * A0-A5 bitfield values:
- *
- * 00b Argument not present
- * 01b 32-bit argument present
- * 10b 64-bit argument present
- * 11b Reserved
- */
-#define TRC_PV_HYPERCALL_V2_ARG_32(i) (0x1 << (20 + 2*(i)))
-#define TRC_PV_HYPERCALL_V2_ARG_64(i) (0x2 << (20 + 2*(i)))
-#define TRC_PV_HYPERCALL_V2_ARG_MASK (0xfff00000)
-
-#define TRC_SHADOW_NOT_SHADOW (TRC_SHADOW + 1)
-#define TRC_SHADOW_FAST_PROPAGATE (TRC_SHADOW + 2)
-#define TRC_SHADOW_FAST_MMIO (TRC_SHADOW + 3)
-#define TRC_SHADOW_FALSE_FAST_PATH (TRC_SHADOW + 4)
-#define TRC_SHADOW_MMIO (TRC_SHADOW + 5)
-#define TRC_SHADOW_FIXUP (TRC_SHADOW + 6)
-#define TRC_SHADOW_DOMF_DYING (TRC_SHADOW + 7)
-#define TRC_SHADOW_EMULATE (TRC_SHADOW + 8)
-#define TRC_SHADOW_EMULATE_UNSHADOW_USER (TRC_SHADOW + 9)
-#define TRC_SHADOW_EMULATE_UNSHADOW_EVTINJ (TRC_SHADOW + 10)
-#define TRC_SHADOW_EMULATE_UNSHADOW_UNHANDLED (TRC_SHADOW + 11)
-#define TRC_SHADOW_WRMAP_BF (TRC_SHADOW + 12)
-#define TRC_SHADOW_PREALLOC_UNPIN (TRC_SHADOW + 13)
-#define TRC_SHADOW_RESYNC_FULL (TRC_SHADOW + 14)
-#define TRC_SHADOW_RESYNC_ONLY (TRC_SHADOW + 15)
-
-/* trace events per subclass */
-#define TRC_HVM_NESTEDFLAG (0x400)
-#define TRC_HVM_VMENTRY (TRC_HVM_ENTRYEXIT + 0x01)
-#define TRC_HVM_VMEXIT (TRC_HVM_ENTRYEXIT + 0x02)
-#define TRC_HVM_VMEXIT64 (TRC_HVM_ENTRYEXIT + TRC_64_FLAG + 0x02)
-#define TRC_HVM_PF_XEN (TRC_HVM_HANDLER + 0x01)
-#define TRC_HVM_PF_XEN64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x01)
-#define TRC_HVM_PF_INJECT (TRC_HVM_HANDLER + 0x02)
-#define TRC_HVM_PF_INJECT64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x02)
-#define TRC_HVM_INJ_EXC (TRC_HVM_HANDLER + 0x03)
-#define TRC_HVM_INJ_VIRQ (TRC_HVM_HANDLER + 0x04)
-#define TRC_HVM_REINJ_VIRQ (TRC_HVM_HANDLER + 0x05)
-#define TRC_HVM_IO_READ (TRC_HVM_HANDLER + 0x06)
-#define TRC_HVM_IO_WRITE (TRC_HVM_HANDLER + 0x07)
-#define TRC_HVM_CR_READ (TRC_HVM_HANDLER + 0x08)
-#define TRC_HVM_CR_READ64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x08)
-#define TRC_HVM_CR_WRITE (TRC_HVM_HANDLER + 0x09)
-#define TRC_HVM_CR_WRITE64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x09)
-#define TRC_HVM_DR_READ (TRC_HVM_HANDLER + 0x0A)
-#define TRC_HVM_DR_WRITE (TRC_HVM_HANDLER + 0x0B)
-#define TRC_HVM_MSR_READ (TRC_HVM_HANDLER + 0x0C)
-#define TRC_HVM_MSR_WRITE (TRC_HVM_HANDLER + 0x0D)
-#define TRC_HVM_CPUID (TRC_HVM_HANDLER + 0x0E)
-#define TRC_HVM_INTR (TRC_HVM_HANDLER + 0x0F)
-#define TRC_HVM_NMI (TRC_HVM_HANDLER + 0x10)
-#define TRC_HVM_SMI (TRC_HVM_HANDLER + 0x11)
-#define TRC_HVM_VMMCALL (TRC_HVM_HANDLER + 0x12)
-#define TRC_HVM_HLT (TRC_HVM_HANDLER + 0x13)
-#define TRC_HVM_INVLPG (TRC_HVM_HANDLER + 0x14)
-#define TRC_HVM_INVLPG64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x14)
-#define TRC_HVM_MCE (TRC_HVM_HANDLER + 0x15)
-#define TRC_HVM_IOPORT_READ (TRC_HVM_HANDLER + 0x16)
-#define TRC_HVM_IOMEM_READ (TRC_HVM_HANDLER + 0x17)
-#define TRC_HVM_CLTS (TRC_HVM_HANDLER + 0x18)
-#define TRC_HVM_LMSW (TRC_HVM_HANDLER + 0x19)
-#define TRC_HVM_LMSW64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x19)
-#define TRC_HVM_RDTSC (TRC_HVM_HANDLER + 0x1a)
-#define TRC_HVM_INTR_WINDOW (TRC_HVM_HANDLER + 0x20)
-#define TRC_HVM_NPF (TRC_HVM_HANDLER + 0x21)
-#define TRC_HVM_REALMODE_EMULATE (TRC_HVM_HANDLER + 0x22)
-#define TRC_HVM_TRAP (TRC_HVM_HANDLER + 0x23)
-#define TRC_HVM_TRAP_DEBUG (TRC_HVM_HANDLER + 0x24)
-#define TRC_HVM_VLAPIC (TRC_HVM_HANDLER + 0x25)
-
-#define TRC_HVM_IOPORT_WRITE (TRC_HVM_HANDLER + 0x216)
-#define TRC_HVM_IOMEM_WRITE (TRC_HVM_HANDLER + 0x217)
-
-/* Trace events for emulated devices */
-#define TRC_HVM_EMUL_HPET_START_TIMER (TRC_HVM_EMUL + 0x1)
-#define TRC_HVM_EMUL_PIT_START_TIMER (TRC_HVM_EMUL + 0x2)
-#define TRC_HVM_EMUL_RTC_START_TIMER (TRC_HVM_EMUL + 0x3)
-#define TRC_HVM_EMUL_LAPIC_START_TIMER (TRC_HVM_EMUL + 0x4)
-#define TRC_HVM_EMUL_HPET_STOP_TIMER (TRC_HVM_EMUL + 0x5)
-#define TRC_HVM_EMUL_PIT_STOP_TIMER (TRC_HVM_EMUL + 0x6)
-#define TRC_HVM_EMUL_RTC_STOP_TIMER (TRC_HVM_EMUL + 0x7)
-#define TRC_HVM_EMUL_LAPIC_STOP_TIMER (TRC_HVM_EMUL + 0x8)
-#define TRC_HVM_EMUL_PIT_TIMER_CB (TRC_HVM_EMUL + 0x9)
-#define TRC_HVM_EMUL_LAPIC_TIMER_CB (TRC_HVM_EMUL + 0xA)
-#define TRC_HVM_EMUL_PIC_INT_OUTPUT (TRC_HVM_EMUL + 0xB)
-#define TRC_HVM_EMUL_PIC_KICK (TRC_HVM_EMUL + 0xC)
-#define TRC_HVM_EMUL_PIC_INTACK (TRC_HVM_EMUL + 0xD)
-#define TRC_HVM_EMUL_PIC_POSEDGE (TRC_HVM_EMUL + 0xE)
-#define TRC_HVM_EMUL_PIC_NEGEDGE (TRC_HVM_EMUL + 0xF)
-#define TRC_HVM_EMUL_PIC_PEND_IRQ_CALL (TRC_HVM_EMUL + 0x10)
-#define TRC_HVM_EMUL_LAPIC_PIC_INTR (TRC_HVM_EMUL + 0x11)
-
-/* trace events for per class */
-#define TRC_PM_FREQ_CHANGE (TRC_HW_PM + 0x01)
-#define TRC_PM_IDLE_ENTRY (TRC_HW_PM + 0x02)
-#define TRC_PM_IDLE_EXIT (TRC_HW_PM + 0x03)
-
-/* Trace events for IRQs */
-#define TRC_HW_IRQ_MOVE_CLEANUP_DELAY (TRC_HW_IRQ + 0x1)
-#define TRC_HW_IRQ_MOVE_CLEANUP (TRC_HW_IRQ + 0x2)
-#define TRC_HW_IRQ_BIND_VECTOR (TRC_HW_IRQ + 0x3)
-#define TRC_HW_IRQ_CLEAR_VECTOR (TRC_HW_IRQ + 0x4)
-#define TRC_HW_IRQ_MOVE_FINISH (TRC_HW_IRQ + 0x5)
-#define TRC_HW_IRQ_ASSIGN_VECTOR (TRC_HW_IRQ + 0x6)
-#define TRC_HW_IRQ_UNMAPPED_VECTOR (TRC_HW_IRQ + 0x7)
-#define TRC_HW_IRQ_HANDLED (TRC_HW_IRQ + 0x8)
-
-/*
- * Event Flags
- *
- * Some events (e.g, TRC_PV_TRAP and TRC_HVM_IOMEM_READ) have multiple
- * record formats. These event flags distinguish between the
- * different formats.
- */
-#define TRC_64_FLAG 0x100 /* Addresses are 64 bits (instead of 32 bits) */
-
-/* This structure represents a single trace buffer record. */
-struct t_rec {
- uint32_t event:28;
- uint32_t extra_u32:3; /* # entries in trailing extra_u32[] array */
- uint32_t cycles_included:1; /* u.cycles or u.no_cycles? */
- union {
- struct {
- uint32_t cycles_lo, cycles_hi; /* cycle counter timestamp */
- uint32_t extra_u32[7]; /* event data items */
- } cycles;
- struct {
- uint32_t extra_u32[7]; /* event data items */
- } nocycles;
- } u;
-};
-
-/*
- * This structure contains the metadata for a single trace buffer. The head
- * field, indexes into an array of struct t_rec's.
- */
-struct t_buf {
- /* Assume the data buffer size is X. X is generally not a power of 2.
- * CONS and PROD are incremented modulo (2*X):
- * 0 <= cons < 2*X
- * 0 <= prod < 2*X
- * This is done because addition modulo X breaks at 2^32 when X is not a
- * power of 2:
- * (((2^32 - 1) % X) + 1) % X != (2^32) % X
- */
- uint32_t cons; /* Offset of next item to be consumed by control tools. */
- uint32_t prod; /* Offset of next item to be produced by Xen. */
- /* Records follow immediately after the meta-data header. */
-};
-
-/* Structure used to pass MFNs to the trace buffers back to trace consumers.
- * Offset is an offset into the mapped structure where the mfn list will be held.
- * MFNs will be at ((unsigned long *)(t_info))+(t_info->cpu_offset[cpu]).
- */
-struct t_info {
- uint16_t tbuf_size; /* Size in pages of each trace buffer */
- uint16_t mfn_offset[]; /* Offset within t_info structure of the page list per cpu */
- /* MFN lists immediately after the header */
-};
-
-#endif /* __XEN_PUBLIC_TRACE_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * vcpu.h
- *
- * VCPU initialisation, query, and hotplug.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_VCPU_H__
-#define __XEN_PUBLIC_VCPU_H__
-
-#include "xen.h"
-
-/*
- * Prototype for this hypercall is:
- * long vcpu_op(int cmd, unsigned int vcpuid, void *extra_args)
- * @cmd == VCPUOP_??? (VCPU operation).
- * @vcpuid == VCPU to operate on.
- * @extra_args == Operation-specific extra arguments (NULL if none).
- */
-
-/*
- * Initialise a VCPU. Each VCPU can be initialised only once. A
- * newly-initialised VCPU will not run until it is brought up by VCPUOP_up.
- *
- * @extra_arg == pointer to vcpu_guest_context structure containing initial
- * state for the VCPU.
- */
-#define VCPUOP_initialise 0
-
-/*
- * Bring up a VCPU. This makes the VCPU runnable. This operation will fail
- * if the VCPU has not been initialised (VCPUOP_initialise).
- */
-#define VCPUOP_up 1
-
-/*
- * Bring down a VCPU (i.e., make it non-runnable).
- * There are a few caveats that callers should observe:
- * 1. This operation may return, and VCPU_is_up may return false, before the
- * VCPU stops running (i.e., the command is asynchronous). It is a good
- * idea to ensure that the VCPU has entered a non-critical loop before
- * bringing it down. Alternatively, this operation is guaranteed
- * synchronous if invoked by the VCPU itself.
- * 2. After a VCPU is initialised, there is currently no way to drop all its
- * references to domain memory. Even a VCPU that is down still holds
- * memory references via its pagetable base pointer and GDT. It is good
- * practise to move a VCPU onto an 'idle' or default page table, LDT and
- * GDT before bringing it down.
- */
-#define VCPUOP_down 2
-
-/* Returns 1 if the given VCPU is up. */
-#define VCPUOP_is_up 3
-
-/*
- * Return information about the state and running time of a VCPU.
- * @extra_arg == pointer to vcpu_runstate_info structure.
- */
-#define VCPUOP_get_runstate_info 4
-struct vcpu_runstate_info {
- /* VCPU's current state (RUNSTATE_*). */
- int state;
- /* When was current state entered (system time, ns)? */
- uint64_t state_entry_time;
- /*
- * Time spent in each RUNSTATE_* (ns). The sum of these times is
- * guaranteed not to drift from system time.
- */
- uint64_t time[4];
-};
-typedef struct vcpu_runstate_info vcpu_runstate_info_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t);
-
-/* VCPU is currently running on a physical CPU. */
-#define RUNSTATE_running 0
-
-/* VCPU is runnable, but not currently scheduled on any physical CPU. */
-#define RUNSTATE_runnable 1
-
-/* VCPU is blocked (a.k.a. idle). It is therefore not runnable. */
-#define RUNSTATE_blocked 2
-
-/*
- * VCPU is not runnable, but it is not blocked.
- * This is a 'catch all' state for things like hotplug and pauses by the
- * system administrator (or for critical sections in the hypervisor).
- * RUNSTATE_blocked dominates this state (it is the preferred state).
- */
-#define RUNSTATE_offline 3
-
-/*
- * Register a shared memory area from which the guest may obtain its own
- * runstate information without needing to execute a hypercall.
- * Notes:
- * 1. The registered address may be virtual or physical or guest handle,
- * depending on the platform. Virtual address or guest handle should be
- * registered on x86 systems.
- * 2. Only one shared area may be registered per VCPU. The shared area is
- * updated by the hypervisor each time the VCPU is scheduled. Thus
- * runstate.state will always be RUNSTATE_running and
- * runstate.state_entry_time will indicate the system time at which the
- * VCPU was last scheduled to run.
- * @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
- */
-#define VCPUOP_register_runstate_memory_area 5
-struct vcpu_register_runstate_memory_area {
- union {
- XEN_GUEST_HANDLE(vcpu_runstate_info_t) h;
- struct vcpu_runstate_info *v;
- uint64_t p;
- } addr;
-};
-typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_memory_area_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_register_runstate_memory_area_t);
-
-/*
- * Set or stop a VCPU's periodic timer. Every VCPU has one periodic timer
- * which can be set via these commands. Periods smaller than one millisecond
- * may not be supported.
- */
-#define VCPUOP_set_periodic_timer 6 /* arg == vcpu_set_periodic_timer_t */
-#define VCPUOP_stop_periodic_timer 7 /* arg == NULL */
-struct vcpu_set_periodic_timer {
- uint64_t period_ns;
-};
-typedef struct vcpu_set_periodic_timer vcpu_set_periodic_timer_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_set_periodic_timer_t);
-
-/*
- * Set or stop a VCPU's single-shot timer. Every VCPU has one single-shot
- * timer which can be set via these commands.
- */
-#define VCPUOP_set_singleshot_timer 8 /* arg == vcpu_set_singleshot_timer_t */
-#define VCPUOP_stop_singleshot_timer 9 /* arg == NULL */
-struct vcpu_set_singleshot_timer {
- uint64_t timeout_abs_ns; /* Absolute system time value in nanoseconds. */
- uint32_t flags; /* VCPU_SSHOTTMR_??? */
-};
-typedef struct vcpu_set_singleshot_timer vcpu_set_singleshot_timer_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_set_singleshot_timer_t);
-
-/* Flags to VCPUOP_set_singleshot_timer. */
- /* Require the timeout to be in the future (return -ETIME if it's passed). */
-#define _VCPU_SSHOTTMR_future (0)
-#define VCPU_SSHOTTMR_future (1U << _VCPU_SSHOTTMR_future)
-
-/*
- * Register a memory location in the guest address space for the
- * vcpu_info structure. This allows the guest to place the vcpu_info
- * structure in a convenient place, such as in a per-cpu data area.
- * The pointer need not be page aligned, but the structure must not
- * cross a page boundary.
- *
- * This may be called only once per vcpu.
- */
-#define VCPUOP_register_vcpu_info 10 /* arg == vcpu_register_vcpu_info_t */
-struct vcpu_register_vcpu_info {
- uint64_t mfn; /* mfn of page to place vcpu_info */
- uint32_t offset; /* offset within page */
- uint32_t rsvd; /* unused */
-};
-typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t);
-
-/* Send an NMI to the specified VCPU. @extra_arg == NULL. */
-#define VCPUOP_send_nmi 11
-
-/*
- * Get the physical ID information for a pinned vcpu's underlying physical
- * processor. The physical ID informmation is architecture-specific.
- * On x86: id[31:0]=apic_id, id[63:32]=acpi_id.
- * This command returns -EINVAL if it is not a valid operation for this VCPU.
- */
-#define VCPUOP_get_physid 12 /* arg == vcpu_get_physid_t */
-struct vcpu_get_physid {
- uint64_t phys_id;
-};
-typedef struct vcpu_get_physid vcpu_get_physid_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
-#define xen_vcpu_physid_to_x86_apicid(physid) ((uint32_t)(physid))
-#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint32_t)((physid) >> 32))
-
-/*
- * Register a memory location to get a secondary copy of the vcpu time
- * parameters. The master copy still exists as part of the vcpu shared
- * memory area, and this secondary copy is updated whenever the master copy
- * is updated (and using the same versioning scheme for synchronisation).
- *
- * The intent is that this copy may be mapped (RO) into userspace so
- * that usermode can compute system time using the time info and the
- * tsc. Usermode will see an array of vcpu_time_info structures, one
- * for each vcpu, and choose the right one by an existing mechanism
- * which allows it to get the current vcpu number (such as via a
- * segment limit). It can then apply the normal algorithm to compute
- * system time from the tsc.
- *
- * @extra_arg == pointer to vcpu_register_time_info_memory_area structure.
- */
-#define VCPUOP_register_vcpu_time_memory_area 13
-DEFINE_XEN_GUEST_HANDLE(vcpu_time_info_t);
-struct vcpu_register_time_memory_area {
- union {
- XEN_GUEST_HANDLE(vcpu_time_info_t) h;
- struct vcpu_time_info *v;
- uint64_t p;
- } addr;
-};
-typedef struct vcpu_register_time_memory_area vcpu_register_time_memory_area_t;
-DEFINE_XEN_GUEST_HANDLE(vcpu_register_time_memory_area_t);
-
-#endif /* __XEN_PUBLIC_VCPU_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * version.h
- *
- * Xen version, type, and compile information.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2005, Nguyen Anh Quynh <aquynh@gmail.com>
- * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
- */
-
-#ifndef __XEN_PUBLIC_VERSION_H__
-#define __XEN_PUBLIC_VERSION_H__
-
-#include "xen.h"
-
-/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
-
-/* arg == NULL; returns major:minor (16:16). */
-#define XENVER_version 0
-
-/* arg == xen_extraversion_t. */
-#define XENVER_extraversion 1
-typedef char xen_extraversion_t[16];
-#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
-
-/* arg == xen_compile_info_t. */
-#define XENVER_compile_info 2
-struct xen_compile_info {
- char compiler[64];
- char compile_by[16];
- char compile_domain[32];
- char compile_date[32];
-};
-typedef struct xen_compile_info xen_compile_info_t;
-
-#define XENVER_capabilities 3
-typedef char xen_capabilities_info_t[1024];
-#define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t))
-
-#define XENVER_changeset 4
-typedef char xen_changeset_info_t[64];
-#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))
-
-#define XENVER_platform_parameters 5
-struct xen_platform_parameters {
- xen_ulong_t virt_start;
-};
-typedef struct xen_platform_parameters xen_platform_parameters_t;
-
-#define XENVER_get_features 6
-struct xen_feature_info {
- unsigned int submap_idx; /* IN: which 32-bit submap to return */
- uint32_t submap; /* OUT: 32-bit submap */
-};
-typedef struct xen_feature_info xen_feature_info_t;
-
-/* Declares the features reported by XENVER_get_features. */
-#include "features.h"
-
-/* arg == NULL; returns host memory page size. */
-#define XENVER_pagesize 7
-
-/* arg == xen_domain_handle_t. */
-#define XENVER_guest_handle 8
-
-#define XENVER_commandline 9
-typedef char xen_commandline_t[1024];
-
-#endif /* __XEN_PUBLIC_VERSION_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * xen-compat.h
- *
- * Guest OS interface to Xen. Compatibility layer.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2006, Christian Limpach
- */
-
-#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
-#define __XEN_PUBLIC_XEN_COMPAT_H__
-
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040600
-
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-/* Xen is built with matching headers and implements the latest interface. */
-#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__
-#elif !defined(__XEN_INTERFACE_VERSION__)
-/* Guests which do not specify a version get the legacy interface. */
-#define __XEN_INTERFACE_VERSION__ 0x00000000
-#endif
-
-#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__
-#error "These header files do not support the requested interface version."
-#endif
-
-#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
+++ /dev/null
-/******************************************************************************
- * xen.h
- *
- * Guest OS interface to Xen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __XEN_PUBLIC_XEN_H__
-#define __XEN_PUBLIC_XEN_H__
-
-#include "xen-compat.h"
-
-#if defined(__i386__) || defined(__x86_64__)
-#include "arch-x86/xen.h"
-#elif defined(__arm__) || defined (__aarch64__)
-#include "arch-arm.h"
-#else
-#error "Unsupported architecture"
-#endif
-
-#ifndef __ASSEMBLY__
-/* Guest handles for primitive C types. */
-DEFINE_XEN_GUEST_HANDLE(char);
-__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
-DEFINE_XEN_GUEST_HANDLE(int);
-__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int);
-#if __XEN_INTERFACE_VERSION__ < 0x00040300
-DEFINE_XEN_GUEST_HANDLE(long);
-__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
-#endif
-DEFINE_XEN_GUEST_HANDLE(void);
-
-DEFINE_XEN_GUEST_HANDLE(uint64_t);
-DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
-DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
-#endif
-
-/*
- * HYPERCALLS
- */
-
-/* `incontents 100 hcalls List of hypercalls
- * ` enum hypercall_num { // __HYPERVISOR_* => HYPERVISOR_*()
- */
-
-#define __HYPERVISOR_set_trap_table 0
-#define __HYPERVISOR_mmu_update 1
-#define __HYPERVISOR_set_gdt 2
-#define __HYPERVISOR_stack_switch 3
-#define __HYPERVISOR_set_callbacks 4
-#define __HYPERVISOR_fpu_taskswitch 5
-#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */
-#define __HYPERVISOR_platform_op 7
-#define __HYPERVISOR_set_debugreg 8
-#define __HYPERVISOR_get_debugreg 9
-#define __HYPERVISOR_update_descriptor 10
-#define __HYPERVISOR_memory_op 12
-#define __HYPERVISOR_multicall 13
-#define __HYPERVISOR_update_va_mapping 14
-#define __HYPERVISOR_set_timer_op 15
-#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
-#define __HYPERVISOR_xen_version 17
-#define __HYPERVISOR_console_io 18
-#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */
-#define __HYPERVISOR_grant_table_op 20
-#define __HYPERVISOR_vm_assist 21
-#define __HYPERVISOR_update_va_mapping_otherdomain 22
-#define __HYPERVISOR_iret 23 /* x86 only */
-#define __HYPERVISOR_vcpu_op 24
-#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
-#define __HYPERVISOR_mmuext_op 26
-#define __HYPERVISOR_xsm_op 27
-#define __HYPERVISOR_nmi_op 28
-#define __HYPERVISOR_sched_op 29
-#define __HYPERVISOR_callback_op 30
-#define __HYPERVISOR_xenoprof_op 31
-#define __HYPERVISOR_event_channel_op 32
-#define __HYPERVISOR_physdev_op 33
-#define __HYPERVISOR_hvm_op 34
-#define __HYPERVISOR_sysctl 35
-#define __HYPERVISOR_domctl 36
-#define __HYPERVISOR_kexec_op 37
-#define __HYPERVISOR_tmem_op 38
-#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
-
-/* Architecture-specific hypercall definitions. */
-#define __HYPERVISOR_arch_0 48
-#define __HYPERVISOR_arch_1 49
-#define __HYPERVISOR_arch_2 50
-#define __HYPERVISOR_arch_3 51
-#define __HYPERVISOR_arch_4 52
-#define __HYPERVISOR_arch_5 53
-#define __HYPERVISOR_arch_6 54
-#define __HYPERVISOR_arch_7 55
-
-/* ` } */
-
-/*
- * HYPERCALL COMPATIBILITY.
- */
-
-/* New sched_op hypercall introduced in 0x00030101. */
-#if __XEN_INTERFACE_VERSION__ < 0x00030101
-#undef __HYPERVISOR_sched_op
-#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
-#endif
-
-/* New event-channel and physdev hypercalls introduced in 0x00030202. */
-#if __XEN_INTERFACE_VERSION__ < 0x00030202
-#undef __HYPERVISOR_event_channel_op
-#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
-#undef __HYPERVISOR_physdev_op
-#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
-#endif
-
-/* New platform_op hypercall introduced in 0x00030204. */
-#if __XEN_INTERFACE_VERSION__ < 0x00030204
-#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op
-#endif
-
-/*
- * VIRTUAL INTERRUPTS
- *
- * Virtual interrupts that a guest OS may receive from Xen.
- *
- * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a
- * global VIRQ. The former can be bound once per VCPU and cannot be re-bound.
- * The latter can be allocated only once per guest: they must initially be
- * allocated to VCPU0 but can subsequently be re-bound.
- */
-/* ` enum virq { */
-#define VIRQ_TIMER 0 /* V. Timebase update, and/or requested timeout. */
-#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. */
-#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency console. */
-#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain. */
-#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */
-#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */
-#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
-#define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */
-#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed */
-#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occured */
-#define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient */
-#define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */
-
-/* Architecture-specific VIRQ definitions. */
-#define VIRQ_ARCH_0 16
-#define VIRQ_ARCH_1 17
-#define VIRQ_ARCH_2 18
-#define VIRQ_ARCH_3 19
-#define VIRQ_ARCH_4 20
-#define VIRQ_ARCH_5 21
-#define VIRQ_ARCH_6 22
-#define VIRQ_ARCH_7 23
-/* ` } */
-
-#define NR_VIRQS 24
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_mmu_update(const struct mmu_update reqs[],
- * ` unsigned count, unsigned *done_out,
- * ` unsigned foreigndom)
- * `
- * @reqs is an array of mmu_update_t structures ((ptr, val) pairs).
- * @count is the length of the above array.
- * @pdone is an output parameter indicating number of completed operations
- * @foreigndom[15:0]: FD, the expected owner of data pages referenced in this
- * hypercall invocation. Can be DOMID_SELF.
- * @foreigndom[31:16]: PFD, the expected owner of pagetable pages referenced
- * in this hypercall invocation. The value of this field
- * (x) encodes the PFD as follows:
- * x == 0 => PFD == DOMID_SELF
- * x != 0 => PFD == x - 1
- *
- * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command.
- * -------------
- * ptr[1:0] == MMU_NORMAL_PT_UPDATE:
- * Updates an entry in a page table belonging to PFD. If updating an L1 table,
- * and the new table entry is valid/present, the mapped frame must belong to
- * FD. If attempting to map an I/O page then the caller assumes the privilege
- * of the FD.
- * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
- * FD == DOMID_XEN: Map restricted areas of Xen's heap space.
- * ptr[:2] -- Machine address of the page-table entry to modify.
- * val -- Value to write.
- *
- * There also certain implicit requirements when using this hypercall. The
- * pages that make up a pagetable must be mapped read-only in the guest.
- * This prevents uncontrolled guest updates to the pagetable. Xen strictly
- * enforces this, and will disallow any pagetable update which will end up
- * mapping pagetable page RW, and will disallow using any writable page as a
- * pagetable. In practice it means that when constructing a page table for a
- * process, thread, etc, we MUST be very dilligient in following these rules:
- * 1). Start with top-level page (PGD or in Xen language: L4). Fill out
- * the entries.
- * 2). Keep on going, filling out the upper (PUD or L3), and middle (PMD
- * or L2).
- * 3). Start filling out the PTE table (L1) with the PTE entries. Once
- * done, make sure to set each of those entries to RO (so writeable bit
- * is unset). Once that has been completed, set the PMD (L2) for this
- * PTE table as RO.
- * 4). When completed with all of the PMD (L2) entries, and all of them have
- * been set to RO, make sure to set RO the PUD (L3). Do the same
- * operation on PGD (L4) pagetable entries that have a PUD (L3) entry.
- * 5). Now before you can use those pages (so setting the cr3), you MUST also
- * pin them so that the hypervisor can verify the entries. This is done
- * via the HYPERVISOR_mmuext_op(MMUEXT_PIN_L4_TABLE, guest physical frame
- * number of the PGD (L4)). And this point the HYPERVISOR_mmuext_op(
- * MMUEXT_NEW_BASEPTR, guest physical frame number of the PGD (L4)) can be
- * issued.
- * For 32-bit guests, the L4 is not used (as there is less pagetables), so
- * instead use L3.
- * At this point the pagetables can be modified using the MMU_NORMAL_PT_UPDATE
- * hypercall. Also if so desired the OS can also try to write to the PTE
- * and be trapped by the hypervisor (as the PTE entry is RO).
- *
- * To deallocate the pages, the operations are the reverse of the steps
- * mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and the
- * pagetable MUST not be in use (meaning that the cr3 is not set to it).
- *
- * ptr[1:0] == MMU_MACHPHYS_UPDATE:
- * Updates an entry in the machine->pseudo-physical mapping table.
- * ptr[:2] -- Machine address within the frame whose mapping to modify.
- * The frame must belong to the FD, if one is specified.
- * val -- Value to write into the mapping entry.
- *
- * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD:
- * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed
- * with those in @val.
- *
- * @val is usually the machine frame number along with some attributes.
- * The attributes by default follow the architecture defined bits. Meaning that
- * if this is a X86_64 machine and four page table layout is used, the layout
- * of val is:
- * - 63 if set means No execute (NX)
- * - 46-13 the machine frame number
- * - 12 available for guest
- * - 11 available for guest
- * - 10 available for guest
- * - 9 available for guest
- * - 8 global
- * - 7 PAT (PSE is disabled, must use hypercall to make 4MB or 2MB pages)
- * - 6 dirty
- * - 5 accessed
- * - 4 page cached disabled
- * - 3 page write through
- * - 2 userspace accessible
- * - 1 writeable
- * - 0 present
- *
- * The one bits that does not fit with the default layout is the PAGE_PSE
- * also called PAGE_PAT). The MMUEXT_[UN]MARK_SUPER arguments to the
- * HYPERVISOR_mmuext_op serve as mechanism to set a pagetable to be 4MB
- * (or 2MB) instead of using the PAGE_PSE bit.
- *
- * The reason that the PAGE_PSE (bit 7) is not being utilized is due to Xen
- * using it as the Page Attribute Table (PAT) bit - for details on it please
- * refer to Intel SDM 10.12. The PAT allows to set the caching attributes of
- * pages instead of using MTRRs.
- *
- * The PAT MSR is as follows (it is a 64-bit value, each entry is 8 bits):
- * PAT4 PAT0
- * +-----+-----+----+----+----+-----+----+----+
- * | UC | UC- | WC | WB | UC | UC- | WC | WB | <= Linux
- * +-----+-----+----+----+----+-----+----+----+
- * | UC | UC- | WT | WB | UC | UC- | WT | WB | <= BIOS (default when machine boots)
- * +-----+-----+----+----+----+-----+----+----+
- * | rsv | rsv | WP | WC | UC | UC- | WT | WB | <= Xen
- * +-----+-----+----+----+----+-----+----+----+
- *
- * The lookup of this index table translates to looking up
- * Bit 7, Bit 4, and Bit 3 of val entry:
- *
- * PAT/PSE (bit 7) ... PCD (bit 4) .. PWT (bit 3).
- *
- * If all bits are off, then we are using PAT0. If bit 3 turned on,
- * then we are using PAT1, if bit 3 and bit 4, then PAT2..
- *
- * As you can see, the Linux PAT1 translates to PAT4 under Xen. Which means
- * that if a guest that follows Linux's PAT setup and would like to set Write
- * Combined on pages it MUST use PAT4 entry. Meaning that Bit 7 (PAGE_PAT) is
- * set. For example, under Linux it only uses PAT0, PAT1, and PAT2 for the
- * caching as:
- *
- * WB = none (so PAT0)
- * WC = PWT (bit 3 on)
- * UC = PWT | PCD (bit 3 and 4 are on).
- *
- * To make it work with Xen, it needs to translate the WC bit as so:
- *
- * PWT (so bit 3 on) --> PAT (so bit 7 is on) and clear bit 3
- *
- * And to translate back it would:
- *
- * PAT (bit 7 on) --> PWT (bit 3 on) and clear bit 7.
- */
-#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */
-#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */
-#define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */
-
-/*
- * MMU EXTENDED OPERATIONS
- *
- * ` enum neg_errnoval
- * ` HYPERVISOR_mmuext_op(mmuext_op_t uops[],
- * ` unsigned int count,
- * ` unsigned int *pdone,
- * ` unsigned int foreigndom)
- */
-/* HYPERVISOR_mmuext_op() accepts a list of mmuext_op structures.
- * A foreigndom (FD) can be specified (or DOMID_SELF for none).
- * Where the FD has some effect, it is described below.
- *
- * cmd: MMUEXT_(UN)PIN_*_TABLE
- * mfn: Machine frame number to be (un)pinned as a p.t. page.
- * The frame must belong to the FD, if one is specified.
- *
- * cmd: MMUEXT_NEW_BASEPTR
- * mfn: Machine frame number of new page-table base to install in MMU.
- *
- * cmd: MMUEXT_NEW_USER_BASEPTR [x86/64 only]
- * mfn: Machine frame number of new page-table base to install in MMU
- * when in user space.
- *
- * cmd: MMUEXT_TLB_FLUSH_LOCAL
- * No additional arguments. Flushes local TLB.
- *
- * cmd: MMUEXT_INVLPG_LOCAL
- * linear_addr: Linear address to be flushed from the local TLB.
- *
- * cmd: MMUEXT_TLB_FLUSH_MULTI
- * vcpumask: Pointer to bitmap of VCPUs to be flushed.
- *
- * cmd: MMUEXT_INVLPG_MULTI
- * linear_addr: Linear address to be flushed.
- * vcpumask: Pointer to bitmap of VCPUs to be flushed.
- *
- * cmd: MMUEXT_TLB_FLUSH_ALL
- * No additional arguments. Flushes all VCPUs' TLBs.
- *
- * cmd: MMUEXT_INVLPG_ALL
- * linear_addr: Linear address to be flushed from all VCPUs' TLBs.
- *
- * cmd: MMUEXT_FLUSH_CACHE
- * No additional arguments. Writes back and flushes cache contents.
- *
- * cmd: MMUEXT_FLUSH_CACHE_GLOBAL
- * No additional arguments. Writes back and flushes cache contents
- * on all CPUs in the system.
- *
- * cmd: MMUEXT_SET_LDT
- * linear_addr: Linear address of LDT base (NB. must be page-aligned).
- * nr_ents: Number of entries in LDT.
- *
- * cmd: MMUEXT_CLEAR_PAGE
- * mfn: Machine frame number to be cleared.
- *
- * cmd: MMUEXT_COPY_PAGE
- * mfn: Machine frame number of the destination page.
- * src_mfn: Machine frame number of the source page.
- *
- * cmd: MMUEXT_[UN]MARK_SUPER
- * mfn: Machine frame number of head of superpage to be [un]marked.
- */
-/* ` enum mmuext_cmd { */
-#define MMUEXT_PIN_L1_TABLE 0
-#define MMUEXT_PIN_L2_TABLE 1
-#define MMUEXT_PIN_L3_TABLE 2
-#define MMUEXT_PIN_L4_TABLE 3
-#define MMUEXT_UNPIN_TABLE 4
-#define MMUEXT_NEW_BASEPTR 5
-#define MMUEXT_TLB_FLUSH_LOCAL 6
-#define MMUEXT_INVLPG_LOCAL 7
-#define MMUEXT_TLB_FLUSH_MULTI 8
-#define MMUEXT_INVLPG_MULTI 9
-#define MMUEXT_TLB_FLUSH_ALL 10
-#define MMUEXT_INVLPG_ALL 11
-#define MMUEXT_FLUSH_CACHE 12
-#define MMUEXT_SET_LDT 13
-#define MMUEXT_NEW_USER_BASEPTR 15
-#define MMUEXT_CLEAR_PAGE 16
-#define MMUEXT_COPY_PAGE 17
-#define MMUEXT_FLUSH_CACHE_GLOBAL 18
-#define MMUEXT_MARK_SUPER 19
-#define MMUEXT_UNMARK_SUPER 20
-/* ` } */
-
-#ifndef __ASSEMBLY__
-struct mmuext_op {
- unsigned int cmd; /* => enum mmuext_cmd */
- union {
- /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR
- * CLEAR_PAGE, COPY_PAGE, [UN]MARK_SUPER */
- xen_pfn_t mfn;
- /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
- unsigned long linear_addr;
- } arg1;
- union {
- /* SET_LDT */
- unsigned int nr_ents;
- /* TLB_FLUSH_MULTI, INVLPG_MULTI */
-#if __XEN_INTERFACE_VERSION__ >= 0x00030205
- XEN_GUEST_HANDLE(const_void) vcpumask;
-#else
- const void *vcpumask;
-#endif
- /* COPY_PAGE */
- xen_pfn_t src_mfn;
- } arg2;
-};
-typedef struct mmuext_op mmuext_op_t;
-DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
-#endif
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_update_va_mapping(unsigned long va, u64 val,
- * ` enum uvm_flags flags)
- * `
- * ` enum neg_errnoval
- * ` HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, u64 val,
- * ` enum uvm_flags flags,
- * ` domid_t domid)
- * `
- * ` @va: The virtual address whose mapping we want to change
- * ` @val: The new page table entry, must contain a machine address
- * ` @flags: Control TLB flushes
- */
-/* These are passed as 'flags' to update_va_mapping. They can be ORed. */
-/* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap. */
-/* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer. */
-/* ` enum uvm_flags { */
-#define UVMF_NONE (0UL<<0) /* No flushing at all. */
-#define UVMF_TLB_FLUSH (1UL<<0) /* Flush entire TLB(s). */
-#define UVMF_INVLPG (2UL<<0) /* Flush only one entry. */
-#define UVMF_FLUSHTYPE_MASK (3UL<<0)
-#define UVMF_MULTI (0UL<<2) /* Flush subset of TLBs. */
-#define UVMF_LOCAL (0UL<<2) /* Flush local TLB. */
-#define UVMF_ALL (1UL<<2) /* Flush all TLBs. */
-/* ` } */
-
-/*
- * Commands to HYPERVISOR_console_io().
- */
-#define CONSOLEIO_write 0
-#define CONSOLEIO_read 1
-
-/*
- * Commands to HYPERVISOR_vm_assist().
- */
-#define VMASST_CMD_enable 0
-#define VMASST_CMD_disable 1
-
-/* x86/32 guests: simulate full 4GB segment limits. */
-#define VMASST_TYPE_4gb_segments 0
-
-/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */
-#define VMASST_TYPE_4gb_segments_notify 1
-
-/*
- * x86 guests: support writes to bottom-level PTEs.
- * NB1. Page-directory entries cannot be written.
- * NB2. Guest must continue to remove all writable mappings of PTEs.
- */
-#define VMASST_TYPE_writable_pagetables 2
-
-/* x86/PAE guests: support PDPTs above 4GB. */
-#define VMASST_TYPE_pae_extended_cr3 3
-
-#define MAX_VMASST_TYPE 3
-
-#ifndef __ASSEMBLY__
-
-typedef uint16_t domid_t;
-
-/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
-#define DOMID_FIRST_RESERVED (0x7FF0U)
-
-/* DOMID_SELF is used in certain contexts to refer to oneself. */
-#define DOMID_SELF (0x7FF0U)
-
-/*
- * DOMID_IO is used to restrict page-table updates to mapping I/O memory.
- * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO
- * is useful to ensure that no mappings to the OS's own heap are accidentally
- * installed. (e.g., in Linux this could cause havoc as reference counts
- * aren't adjusted on the I/O-mapping code path).
- * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
- * be specified by any calling domain.
- */
-#define DOMID_IO (0x7FF1U)
-
-/*
- * DOMID_XEN is used to allow privileged domains to map restricted parts of
- * Xen's heap space (e.g., the machine_to_phys table).
- * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
- * the caller is privileged.
- */
-#define DOMID_XEN (0x7FF2U)
-
-/*
- * DOMID_COW is used as the owner of sharable pages */
-#define DOMID_COW (0x7FF3U)
-
-/* DOMID_INVALID is used to identify pages with unknown owner. */
-#define DOMID_INVALID (0x7FF4U)
-
-/* Idle domain. */
-#define DOMID_IDLE (0x7FFFU)
-
-/*
- * Send an array of these to HYPERVISOR_mmu_update().
- * NB. The fields are natural pointer/address size for this architecture.
- */
-struct mmu_update {
- uint64_t ptr; /* Machine address of PTE. */
- uint64_t val; /* New contents of PTE. */
-};
-typedef struct mmu_update mmu_update_t;
-DEFINE_XEN_GUEST_HANDLE(mmu_update_t);
-
-/*
- * ` enum neg_errnoval
- * ` HYPERVISOR_multicall(multicall_entry_t call_list[],
- * ` uint32_t nr_calls);
- *
- * NB. The fields are logically the natural register size for this
- * architecture. In cases where xen_ulong_t is larger than this then
- * any unused bits in the upper portion must be zero.
- */
-struct multicall_entry {
- xen_ulong_t op, result;
- xen_ulong_t args[6];
-};
-typedef struct multicall_entry multicall_entry_t;
-DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);
-
-#if __XEN_INTERFACE_VERSION__ < 0x00040400
-/*
- * Event channel endpoints per domain (when using the 2-level ABI):
- * 1024 if a long is 32 bits; 4096 if a long is 64 bits.
- */
-#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS
-#endif
-
-struct vcpu_time_info {
- /*
- * Updates to the following values are preceded and followed by an
- * increment of 'version'. The guest can therefore detect updates by
- * looking for changes to 'version'. If the least-significant bit of
- * the version number is set then an update is in progress and the guest
- * must wait to read a consistent set of values.
- * The correct way to interact with the version number is similar to
- * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
- */
- uint32_t version;
- uint32_t pad0;
- uint64_t tsc_timestamp; /* TSC at last update of time vals. */
- uint64_t system_time; /* Time, in nanosecs, since boot. */
- /*
- * Current system time:
- * system_time +
- * ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32)
- * CPU frequency (Hz):
- * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
- */
- uint32_t tsc_to_system_mul;
- int8_t tsc_shift;
- int8_t pad1[3];
-}; /* 32 bytes */
-typedef struct vcpu_time_info vcpu_time_info_t;
-
-struct vcpu_info {
- /*
- * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
- * a pending notification for a particular VCPU. It is then cleared
- * by the guest OS /before/ checking for pending work, thus avoiding
- * a set-and-check race. Note that the mask is only accessed by Xen
- * on the CPU that is currently hosting the VCPU. This means that the
- * pending and mask flags can be updated by the guest without special
- * synchronisation (i.e., no need for the x86 LOCK prefix).
- * This may seem suboptimal because if the pending flag is set by
- * a different CPU then an IPI may be scheduled even when the mask
- * is set. However, note:
- * 1. The task of 'interrupt holdoff' is covered by the per-event-
- * channel mask bits. A 'noisy' event that is continually being
- * triggered can be masked at source at this very precise
- * granularity.
- * 2. The main purpose of the per-VCPU mask is therefore to restrict
- * reentrant execution: whether for concurrency control, or to
- * prevent unbounded stack usage. Whatever the purpose, we expect
- * that the mask will be asserted only for short periods at a time,
- * and so the likelihood of a 'spurious' IPI is suitably small.
- * The mask is read before making an event upcall to the guest: a
- * non-zero mask therefore guarantees that the VCPU will not receive
- * an upcall activation. The mask is cleared when the VCPU requests
- * to block: this avoids wakeup-waiting races.
- */
- uint8_t evtchn_upcall_pending;
-#ifdef XEN_HAVE_PV_UPCALL_MASK
- uint8_t evtchn_upcall_mask;
-#else /* XEN_HAVE_PV_UPCALL_MASK */
- uint8_t pad0;
-#endif /* XEN_HAVE_PV_UPCALL_MASK */
- xen_ulong_t evtchn_pending_sel;
- struct arch_vcpu_info arch;
- struct vcpu_time_info time;
-}; /* 64 bytes (x86) */
-#ifndef __XEN__
-typedef struct vcpu_info vcpu_info_t;
-#endif
-
-/*
- * `incontents 200 startofday_shared Start-of-day shared data structure
- * Xen/kernel shared data -- pointer provided in start_info.
- *
- * This structure is defined to be both smaller than a page, and the
- * only data on the shared page, but may vary in actual size even within
- * compatible Xen versions; guests should not rely on the size
- * of this structure remaining constant.
- */
-struct shared_info {
- struct vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS];
-
- /*
- * A domain can create "event channels" on which it can send and receive
- * asynchronous event notifications. There are three classes of event that
- * are delivered by this mechanism:
- * 1. Bi-directional inter- and intra-domain connections. Domains must
- * arrange out-of-band to set up a connection (usually by allocating
- * an unbound 'listener' port and avertising that via a storage service
- * such as xenstore).
- * 2. Physical interrupts. A domain with suitable hardware-access
- * privileges can bind an event-channel port to a physical interrupt
- * source.
- * 3. Virtual interrupts ('events'). A domain can bind an event-channel
- * port to a virtual interrupt source, such as the virtual-timer
- * device or the emergency console.
- *
- * Event channels are addressed by a "port index". Each channel is
- * associated with two bits of information:
- * 1. PENDING -- notifies the domain that there is a pending notification
- * to be processed. This bit is cleared by the guest.
- * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING
- * will cause an asynchronous upcall to be scheduled. This bit is only
- * updated by the guest. It is read-only within Xen. If a channel
- * becomes pending while the channel is masked then the 'edge' is lost
- * (i.e., when the channel is unmasked, the guest must manually handle
- * pending notifications as no upcall will be scheduled by Xen).
- *
- * To expedite scanning of pending notifications, any 0->1 pending
- * transition on an unmasked channel causes a corresponding bit in a
- * per-vcpu selector word to be set. Each bit in the selector covers a
- * 'C long' in the PENDING bitfield array.
- */
- xen_ulong_t evtchn_pending[sizeof(xen_ulong_t) * 8];
- xen_ulong_t evtchn_mask[sizeof(xen_ulong_t) * 8];
-
- /*
- * Wallclock time: updated only by control software. Guests should base
- * their gettimeofday() syscall on this wallclock-base value.
- */
- uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */
- uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
- uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */
-
- struct arch_shared_info arch;
-
-};
-#ifndef __XEN__
-typedef struct shared_info shared_info_t;
-#endif
-
-/*
- * `incontents 200 startofday Start-of-day memory layout
- *
- * 1. The domain is started within contiguous virtual-memory region.
- * 2. The contiguous region ends on an aligned 4MB boundary.
- * 3. This the order of bootstrap elements in the initial virtual region:
- * a. relocated kernel image
- * b. initial ram disk [mod_start, mod_len]
- * c. list of allocated page frames [mfn_list, nr_pages]
- * (unless relocated due to XEN_ELFNOTE_INIT_P2M)
- * d. start_info_t structure [register ESI (x86)]
- * e. bootstrap page tables [pt_base and CR3 (x86)]
- * f. bootstrap stack [register ESP (x86)]
- * 4. Bootstrap elements are packed together, but each is 4kB-aligned.
- * 5. The initial ram disk may be omitted.
- * 6. The list of page frames forms a contiguous 'pseudo-physical' memory
- * layout for the domain. In particular, the bootstrap virtual-memory
- * region is a 1:1 mapping to the first section of the pseudo-physical map.
- * 7. All bootstrap elements are mapped read-writable for the guest OS. The
- * only exception is the bootstrap page table, which is mapped read-only.
- * 8. There is guaranteed to be at least 512kB padding after the final
- * bootstrap element. If necessary, the bootstrap virtual region is
- * extended by an extra 4MB to ensure this.
- *
- * Note: Prior to 25833:bb85bbccb1c9. ("x86/32-on-64 adjust Dom0 initial page
- * table layout") a bug caused the pt_base (3.e above) and cr3 to not point
- * to the start of the guest page tables (it was offset by two pages).
- * This only manifested itself on 32-on-64 dom0 kernels and not 32-on-64 domU
- * or 64-bit kernels of any colour. The page tables for a 32-on-64 dom0 got
- * allocated in the order: 'first L1','first L2', 'first L3', so the offset
- * to the page table base is by two pages back. The initial domain if it is
- * 32-bit and runs under a 64-bit hypervisor should _NOT_ use two of the
- * pages preceding pt_base and mark them as reserved/unused.
- */
-#ifdef XEN_HAVE_PV_GUEST_ENTRY
-struct start_info {
- /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
- char magic[32]; /* "xen-<version>-<platform>". */
- unsigned long nr_pages; /* Total pages allocated to this domain. */
- unsigned long shared_info; /* MACHINE address of shared info struct. */
- uint32_t flags; /* SIF_xxx flags. */
- xen_pfn_t store_mfn; /* MACHINE page number of shared page. */
- uint32_t store_evtchn; /* Event channel for store communication. */
- union {
- struct {
- xen_pfn_t mfn; /* MACHINE page number of console page. */
- uint32_t evtchn; /* Event channel for console page. */
- } domU;
- struct {
- uint32_t info_off; /* Offset of console_info struct. */
- uint32_t info_size; /* Size of console_info struct from start.*/
- } dom0;
- } console;
- /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
- unsigned long pt_base; /* VIRTUAL address of page directory. */
- unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */
- unsigned long mfn_list; /* VIRTUAL address of page-frame list. */
- unsigned long mod_start; /* VIRTUAL address of pre-loaded module */
- /* (PFN of pre-loaded module if */
- /* SIF_MOD_START_PFN set in flags). */
- unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
-#define MAX_GUEST_CMDLINE 1024
- int8_t cmd_line[MAX_GUEST_CMDLINE];
- /* The pfn range here covers both page table and p->m table frames. */
- unsigned long first_p2m_pfn;/* 1st pfn forming initial P->M table. */
- unsigned long nr_p2m_frames;/* # of pfns forming initial P->M table. */
-};
-typedef struct start_info start_info_t;
-
-/* New console union for dom0 introduced in 0x00030203. */
-#if __XEN_INTERFACE_VERSION__ < 0x00030203
-#define console_mfn console.domU.mfn
-#define console_evtchn console.domU.evtchn
-#endif
-#endif /* XEN_HAVE_PV_GUEST_ENTRY */
-
-/* These flags are passed in the 'flags' field of start_info_t. */
-#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */
-#define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */
-#define SIF_MULTIBOOT_MOD (1<<2) /* Is mod_start a multiboot module? */
-#define SIF_MOD_START_PFN (1<<3) /* Is mod_start a PFN? */
-#define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */
-
-/*
- * A multiboot module is a package containing modules very similar to a
- * multiboot module array. The only differences are:
- * - the array of module descriptors is by convention simply at the beginning
- * of the multiboot module,
- * - addresses in the module descriptors are based on the beginning of the
- * multiboot module,
- * - the number of modules is determined by a termination descriptor that has
- * mod_start == 0.
- *
- * This permits to both build it statically and reference it in a configuration
- * file, and let the PV guest easily rebase the addresses to virtual addresses
- * and at the same time count the number of modules.
- */
-struct xen_multiboot_mod_list
-{
- /* Address of first byte of the module */
- uint32_t mod_start;
- /* Address of last byte of the module (inclusive) */
- uint32_t mod_end;
- /* Address of zero-terminated command line */
- uint32_t cmdline;
- /* Unused, must be zero */
- uint32_t pad;
-};
-/*
- * `incontents 200 startofday_dom0_console Dom0_console
- *
- * The console structure in start_info.console.dom0
- *
- * This structure includes a variety of information required to
- * have a working VGA/VESA console.
- */
-typedef struct dom0_vga_console_info {
- uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
-#define XEN_VGATYPE_TEXT_MODE_3 0x03
-#define XEN_VGATYPE_VESA_LFB 0x23
-#define XEN_VGATYPE_EFI_LFB 0x70
-
- union {
- struct {
- /* Font height, in pixels. */
- uint16_t font_height;
- /* Cursor location (column, row). */
- uint16_t cursor_x, cursor_y;
- /* Number of rows and columns (dimensions in characters). */
- uint16_t rows, columns;
- } text_mode_3;
-
- struct {
- /* Width and height, in pixels. */
- uint16_t width, height;
- /* Bytes per scan line. */
- uint16_t bytes_per_line;
- /* Bits per pixel. */
- uint16_t bits_per_pixel;
- /* LFB physical address, and size (in units of 64kB). */
- uint32_t lfb_base;
- uint32_t lfb_size;
- /* RGB mask offsets and sizes, as defined by VBE 1.2+ */
- uint8_t red_pos, red_size;
- uint8_t green_pos, green_size;
- uint8_t blue_pos, blue_size;
- uint8_t rsvd_pos, rsvd_size;
-#if __XEN_INTERFACE_VERSION__ >= 0x00030206
- /* VESA capabilities (offset 0xa, VESA command 0x4f00). */
- uint32_t gbl_caps;
- /* Mode attributes (offset 0x0, VESA command 0x4f01). */
- uint16_t mode_attrs;
-#endif
- } vesa_lfb;
- } u;
-} dom0_vga_console_info_t;
-#define xen_vga_console_info dom0_vga_console_info
-#define xen_vga_console_info_t dom0_vga_console_info_t
-
-typedef uint8_t xen_domain_handle_t[16];
-
-/* Turn a plain number into a C unsigned long constant. */
-#define __mk_unsigned_long(x) x ## UL
-#define mk_unsigned_long(x) __mk_unsigned_long(x)
-
-__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t);
-__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t);
-__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t);
-__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
-
-#else /* __ASSEMBLY__ */
-
-/* In assembly code we cannot use C numeric constant suffixes. */
-#define mk_unsigned_long(x) x
-
-#endif /* !__ASSEMBLY__ */
-
-/* Default definitions for macros used by domctl/sysctl. */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-#ifndef uint64_aligned_t
-#define uint64_aligned_t uint64_t
-#endif
-#ifndef XEN_GUEST_HANDLE_64
-#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name)
-#endif
-
-#ifndef __ASSEMBLY__
-struct xenctl_bitmap {
- XEN_GUEST_HANDLE_64(uint8) bitmap;
- uint32_t nr_bits;
-};
-#endif
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
-#endif /* __XEN_PUBLIC_XEN_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) IBM Corp. 2006
- */
-
-#ifndef _XEN_XENCOMM_H_
-#define _XEN_XENCOMM_H_
-
-/* A xencomm descriptor is a scatter/gather list containing physical
- * addresses corresponding to a virtually contiguous memory area. The
- * hypervisor translates these physical addresses to machine addresses to copy
- * to and from the virtually contiguous area.
- */
-
-#define XENCOMM_MAGIC 0x58434F4D /* 'XCOM' */
-#define XENCOMM_INVALID (~0UL)
-
-struct xencomm_desc {
- uint32_t magic;
- uint32_t nr_addrs; /* the number of entries in address[] */
- uint64_t address[0];
-};
-
-#endif /* _XEN_XENCOMM_H_ */
+++ /dev/null
-/******************************************************************************
- * xenoprof.h
- *
- * Interface for enabling system wide profiling based on hardware performance
- * counters
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright (C) 2005 Hewlett-Packard Co.
- * Written by Aravind Menon & Jose Renato Santos
- */
-
-#ifndef __XEN_PUBLIC_XENOPROF_H__
-#define __XEN_PUBLIC_XENOPROF_H__
-
-#include "xen.h"
-
-/*
- * Commands to HYPERVISOR_xenoprof_op().
- */
-#define XENOPROF_init 0
-#define XENOPROF_reset_active_list 1
-#define XENOPROF_reset_passive_list 2
-#define XENOPROF_set_active 3
-#define XENOPROF_set_passive 4
-#define XENOPROF_reserve_counters 5
-#define XENOPROF_counter 6
-#define XENOPROF_setup_events 7
-#define XENOPROF_enable_virq 8
-#define XENOPROF_start 9
-#define XENOPROF_stop 10
-#define XENOPROF_disable_virq 11
-#define XENOPROF_release_counters 12
-#define XENOPROF_shutdown 13
-#define XENOPROF_get_buffer 14
-#define XENOPROF_set_backtrace 15
-
-/* AMD IBS support */
-#define XENOPROF_get_ibs_caps 16
-#define XENOPROF_ibs_counter 17
-#define XENOPROF_last_op 17
-
-#define MAX_OPROF_EVENTS 32
-#define MAX_OPROF_DOMAINS 25
-#define XENOPROF_CPU_TYPE_SIZE 64
-
-/* Xenoprof performance events (not Xen events) */
-struct event_log {
- uint64_t eip;
- uint8_t mode;
- uint8_t event;
-};
-
-/* PC value that indicates a special code */
-#define XENOPROF_ESCAPE_CODE (~0ULL)
-/* Transient events for the xenoprof->oprofile cpu buf */
-#define XENOPROF_TRACE_BEGIN 1
-
-/* Xenoprof buffer shared between Xen and domain - 1 per VCPU */
-struct xenoprof_buf {
- uint32_t event_head;
- uint32_t event_tail;
- uint32_t event_size;
- uint32_t vcpu_id;
- uint64_t xen_samples;
- uint64_t kernel_samples;
- uint64_t user_samples;
- uint64_t lost_samples;
- struct event_log event_log[1];
-};
-#ifndef __XEN__
-typedef struct xenoprof_buf xenoprof_buf_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
-#endif
-
-struct xenoprof_init {
- int32_t num_events;
- int32_t is_primary;
- char cpu_type[XENOPROF_CPU_TYPE_SIZE];
-};
-typedef struct xenoprof_init xenoprof_init_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);
-
-struct xenoprof_get_buffer {
- int32_t max_samples;
- int32_t nbuf;
- int32_t bufsize;
- uint64_t buf_gmaddr;
-};
-typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
-
-struct xenoprof_counter {
- uint32_t ind;
- uint64_t count;
- uint32_t enabled;
- uint32_t event;
- uint32_t hypervisor;
- uint32_t kernel;
- uint32_t user;
- uint64_t unit_mask;
-};
-typedef struct xenoprof_counter xenoprof_counter_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);
-
-typedef struct xenoprof_passive {
- uint16_t domain_id;
- int32_t max_samples;
- int32_t nbuf;
- int32_t bufsize;
- uint64_t buf_gmaddr;
-} xenoprof_passive_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
-
-struct xenoprof_ibs_counter {
- uint64_t op_enabled;
- uint64_t fetch_enabled;
- uint64_t max_cnt_fetch;
- uint64_t max_cnt_op;
- uint64_t rand_en;
- uint64_t dispatched_ops;
-};
-typedef struct xenoprof_ibs_counter xenoprof_ibs_counter_t;
-DEFINE_XEN_GUEST_HANDLE(xenoprof_ibs_counter_t);
-
-#endif /* __XEN_PUBLIC_XENOPROF_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * This file contains the flask_op hypercall commands and definitions.
- *
- * Author: George Coker, <gscoker@alpha.ncsc.mil>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __FLASK_OP_H__
-#define __FLASK_OP_H__
-
-#define XEN_FLASK_INTERFACE_VERSION 1
-
-struct xen_flask_load {
- XEN_GUEST_HANDLE(char) buffer;
- uint32_t size;
-};
-
-struct xen_flask_setenforce {
- uint32_t enforcing;
-};
-
-struct xen_flask_sid_context {
- /* IN/OUT: sid to convert to/from string */
- uint32_t sid;
- /* IN: size of the context buffer
- * OUT: actual size of the output context string
- */
- uint32_t size;
- XEN_GUEST_HANDLE(char) context;
-};
-
-struct xen_flask_access {
- /* IN: access request */
- uint32_t ssid;
- uint32_t tsid;
- uint32_t tclass;
- uint32_t req;
- /* OUT: AVC data */
- uint32_t allowed;
- uint32_t audit_allow;
- uint32_t audit_deny;
- uint32_t seqno;
-};
-
-struct xen_flask_transition {
- /* IN: transition SIDs and class */
- uint32_t ssid;
- uint32_t tsid;
- uint32_t tclass;
- /* OUT: new SID */
- uint32_t newsid;
-};
-
-struct xen_flask_userlist {
- /* IN: starting SID for list */
- uint32_t start_sid;
- /* IN: size of user string and output buffer
- * OUT: number of SIDs returned */
- uint32_t size;
- union {
- /* IN: user to enumerate SIDs */
- XEN_GUEST_HANDLE(char) user;
- /* OUT: SID list */
- XEN_GUEST_HANDLE(uint32) sids;
- } u;
-};
-
-struct xen_flask_boolean {
- /* IN/OUT: numeric identifier for boolean [GET/SET]
- * If -1, name will be used and bool_id will be filled in. */
- uint32_t bool_id;
- /* OUT: current enforcing value of boolean [GET/SET] */
- uint8_t enforcing;
- /* OUT: pending value of boolean [GET/SET] */
- uint8_t pending;
- /* IN: new value of boolean [SET] */
- uint8_t new_value;
- /* IN: commit new value instead of only setting pending [SET] */
- uint8_t commit;
- /* IN: size of boolean name buffer [GET/SET]
- * OUT: actual size of name [GET only] */
- uint32_t size;
- /* IN: if bool_id is -1, used to find boolean [GET/SET]
- * OUT: textual name of boolean [GET only]
- */
- XEN_GUEST_HANDLE(char) name;
-};
-
-struct xen_flask_setavc_threshold {
- /* IN */
- uint32_t threshold;
-};
-
-struct xen_flask_hash_stats {
- /* OUT */
- uint32_t entries;
- uint32_t buckets_used;
- uint32_t buckets_total;
- uint32_t max_chain_len;
-};
-
-struct xen_flask_cache_stats {
- /* IN */
- uint32_t cpu;
- /* OUT */
- uint32_t lookups;
- uint32_t hits;
- uint32_t misses;
- uint32_t allocations;
- uint32_t reclaims;
- uint32_t frees;
-};
-
-struct xen_flask_ocontext {
- /* IN */
- uint32_t ocon;
- uint32_t sid;
- uint64_t low, high;
-};
-
-struct xen_flask_peersid {
- /* IN */
- evtchn_port_t evtchn;
- /* OUT */
- uint32_t sid;
-};
-
-struct xen_flask_relabel {
- /* IN */
- uint32_t domid;
- uint32_t sid;
-};
-
-struct xen_flask_op {
- uint32_t cmd;
-#define FLASK_LOAD 1
-#define FLASK_GETENFORCE 2
-#define FLASK_SETENFORCE 3
-#define FLASK_CONTEXT_TO_SID 4
-#define FLASK_SID_TO_CONTEXT 5
-#define FLASK_ACCESS 6
-#define FLASK_CREATE 7
-#define FLASK_RELABEL 8
-#define FLASK_USER 9
-#define FLASK_POLICYVERS 10
-#define FLASK_GETBOOL 11
-#define FLASK_SETBOOL 12
-#define FLASK_COMMITBOOLS 13
-#define FLASK_MLS 14
-#define FLASK_DISABLE 15
-#define FLASK_GETAVC_THRESHOLD 16
-#define FLASK_SETAVC_THRESHOLD 17
-#define FLASK_AVC_HASHSTATS 18
-#define FLASK_AVC_CACHESTATS 19
-#define FLASK_MEMBER 20
-#define FLASK_ADD_OCONTEXT 21
-#define FLASK_DEL_OCONTEXT 22
-#define FLASK_GET_PEER_SID 23
-#define FLASK_RELABEL_DOMAIN 24
- uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */
- union {
- struct xen_flask_load load;
- struct xen_flask_setenforce enforce;
- /* FLASK_CONTEXT_TO_SID and FLASK_SID_TO_CONTEXT */
- struct xen_flask_sid_context sid_context;
- struct xen_flask_access access;
- /* FLASK_CREATE, FLASK_RELABEL, FLASK_MEMBER */
- struct xen_flask_transition transition;
- struct xen_flask_userlist userlist;
- /* FLASK_GETBOOL, FLASK_SETBOOL */
- struct xen_flask_boolean boolean;
- struct xen_flask_setavc_threshold setavc_threshold;
- struct xen_flask_hash_stats hash_stats;
- struct xen_flask_cache_stats cache_stats;
- /* FLASK_ADD_OCONTEXT, FLASK_DEL_OCONTEXT */
- struct xen_flask_ocontext ocontext;
- struct xen_flask_peersid peersid;
- struct xen_flask_relabel relabel;
- } u;
-};
-typedef struct xen_flask_op xen_flask_op_t;
-DEFINE_XEN_GUEST_HANDLE(xen_flask_op_t);
-
-#endif
+++ /dev/null
-#ifndef XENBUS_H__
-#define XENBUS_H__
-
-#include <xen/io/xenbus.h>
-
-typedef unsigned long xenbus_transaction_t;
-#define XBT_NIL ((xenbus_transaction_t)0)
-
-#ifdef CONFIG_XENBUS
-/* Initialize the XenBus system. */
-void init_xenbus(void);
-#else
-static inline void init_xenbus(void)
-{
-}
-#endif
-
-/* Read the value associated with a path. Returns a malloc'd error
- string on failure and sets *value to NULL. On success, *value is
- set to a malloc'd copy of the value. */
-char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
-
-/* Watch event queue */
-struct xenbus_event {
- /* Keep these two as this for xs.c */
- char *path;
- char *token;
- struct xenbus_event *next;
-};
-typedef struct xenbus_event *xenbus_event_queue;
-
-char *xenbus_watch_path_token(xenbus_transaction_t xbt, const char *path, const char *token, xenbus_event_queue *events);
-char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, const char *path, const char *token);
-extern struct wait_queue_head xenbus_watch_queue;
-void xenbus_wait_for_watch(xenbus_event_queue *queue);
-char **xenbus_wait_for_watch_return(xenbus_event_queue *queue);
-char* xenbus_wait_for_value(const char *path, const char *value, xenbus_event_queue *queue);
-char *xenbus_wait_for_state_change(const char* path, XenbusState *state, xenbus_event_queue *queue);
-char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, XenbusState state);
-
-/* When no token is provided, use a global queue. */
-#define XENBUS_WATCH_PATH_TOKEN "xenbus_watch_path"
-extern xenbus_event_queue xenbus_events;
-#define xenbus_watch_path(xbt, path) xenbus_watch_path_token(xbt, path, XENBUS_WATCH_PATH_TOKEN, NULL)
-#define xenbus_unwatch_path(xbt, path) xenbus_unwatch_path_token(xbt, path, XENBUS_WATCH_PATH_TOKEN)
-
-
-/* Associates a value with a path. Returns a malloc'd error string on
- failure. */
-char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
-
-struct write_req {
- const void *data;
- unsigned len;
-};
-
-/* Send a message to xenbus, in the same fashion as xb_write, and
- block waiting for a reply. The reply is malloced and should be
- freed by the caller. */
-struct xsd_sockmsg *
-xenbus_msg_reply(int type,
- xenbus_transaction_t trans,
- struct write_req *io,
- int nr_reqs);
-
-/* Removes the value associated with a path. Returns a malloc'd error
- string on failure. */
-char *xenbus_rm(xenbus_transaction_t xbt, const char *path);
-
-/* List the contents of a directory. Returns a malloc'd error string
- on failure and sets *contents to NULL. On success, *contents is
- set to a malloc'd array of pointers to malloc'd strings. The array
- is NULL terminated. May block. */
-char *xenbus_ls(xenbus_transaction_t xbt, const char *prefix, char ***contents);
-
-/* Reads permissions associated with a path. Returns a malloc'd error
- string on failure and sets *value to NULL. On success, *value is
- set to a malloc'd copy of the value. */
-char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value);
-
-/* Sets the permissions associated with a path. Returns a malloc'd
- error string on failure. */
-char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm);
-
-/* Start a xenbus transaction. Returns the transaction in xbt on
- success or a malloc'd error string otherwise. */
-char *xenbus_transaction_start(xenbus_transaction_t *xbt);
-
-/* End a xenbus transaction. Returns a malloc'd error string if it
- fails. abort says whether the transaction should be aborted.
- Returns 1 in *retry iff the transaction should be retried. */
-char *xenbus_transaction_end(xenbus_transaction_t, int abort,
- int *retry);
-
-/* Read path and parse it as an integer. Returns -1 on error. */
-int xenbus_read_integer(const char *path);
-
-/* Read path and parse it as 16 byte uuid. Returns 1 if
- * read and parsing were successful, 0 if not */
-int xenbus_read_uuid(const char* path, unsigned char uuid[16]);
-
-/* Contraction of snprintf and xenbus_write(path/node). */
-char* xenbus_printf(xenbus_transaction_t xbt,
- const char* node, const char* path,
- const char* fmt, ...)
- __attribute__((__format__(printf, 4, 5)));
-
-/* Utility function to figure out our domain id */
-domid_t xenbus_get_self_id(void);
-
-#ifdef CONFIG_XENBUS
-/* Reset the XenBus system. */
-void fini_xenbus(void);
-#else
-static inline void fini_xenbus(void)
-{
-}
-#endif
-
-#endif /* XENBUS_H__ */
+++ /dev/null
-#ifndef __XMALLOC_H__
-#define __XMALLOC_H__
-
-#ifdef HAVE_LIBC
-
-#include <stdlib.h>
-#include <malloc.h>
-/* Allocate space for typed object. */
-#define _xmalloc(size, align) memalign(align, size)
-#define xfree(ptr) free(ptr)
-
-#else
-
-#include <limits.h>
-
-#define DEFAULT_ALIGN (sizeof(unsigned long))
-
-extern void *malloc(size_t size);
-extern void *realloc(void *ptr, size_t size);
-extern void free(void *ptr);
-
-/* Free memory from any xmalloc*() call. */
-extern void xfree(const void *);
-
-/* Underlying functions */
-extern void *_xmalloc(size_t size, size_t align);
-
-#endif
-
-static inline void *_xmalloc_array(size_t size, size_t align, size_t num)
-{
- /* Check for overflow. */
- if (size && num > UINT_MAX / size)
- return NULL;
- return _xmalloc(size * num, align);
-}
-
-/* Allocate space for typed object. */
-#define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type)))
-
-/* Allocate space for array of typed objects. */
-#define xmalloc_array(_type, _num) ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
-
-#endif /* __XMALLOC_H__ */
+++ /dev/null
-/******************************************************************************
- * kernel.c
- *
- * Assorted crap goes here, including the initial C entry point, jumped at
- * from head.S.
- *
- * Copyright (c) 2002-2003, K A Fraser & R Neugebauer
- * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge
- * Copyright (c) 2006, Robert Kaiser, FH Wiesbaden
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/kernel.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/mm.h>
-#include <mini-os/events.h>
-#include <mini-os/time.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/sched.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/netfront.h>
-#include <mini-os/blkfront.h>
-#include <mini-os/fbfront.h>
-#include <mini-os/pcifront.h>
-#include <mini-os/xmalloc.h>
-#include <fcntl.h>
-#include <xen/features.h>
-#include <xen/version.h>
-
-uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
-
-void setup_xen_features(void)
-{
- xen_feature_info_t fi;
- int i, j;
-
- for (i = 0; i < XENFEAT_NR_SUBMAPS; i++)
- {
- fi.submap_idx = i;
- if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
- break;
-
- for (j=0; j<32; j++)
- xen_features[i*32+j] = !!(fi.submap & 1<<j);
- }
-}
-
-#ifdef CONFIG_XENBUS
-/* This should be overridden by the application we are linked against. */
-__attribute__((weak)) void app_shutdown(unsigned reason)
-{
- struct sched_shutdown sched_shutdown = { .reason = reason };
- printk("Shutdown requested: %d\n", reason);
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-}
-
-static void shutdown_thread(void *p)
-{
- const char *path = "control/shutdown";
- const char *token = path;
- xenbus_event_queue events = NULL;
- char *shutdown = NULL, *err;
- unsigned int shutdown_reason;
- xenbus_watch_path_token(XBT_NIL, path, token, &events);
- while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL || !strcmp(shutdown, ""))
- {
- free(err);
- free(shutdown);
- shutdown = NULL;
- xenbus_wait_for_watch(&events);
- }
- err = xenbus_unwatch_path_token(XBT_NIL, path, token);
- free(err);
- err = xenbus_write(XBT_NIL, path, "");
- free(err);
- printk("Shutting down (%s)\n", shutdown);
-
- if (!strcmp(shutdown, "poweroff"))
- shutdown_reason = SHUTDOWN_poweroff;
- else if (!strcmp(shutdown, "reboot"))
- shutdown_reason = SHUTDOWN_reboot;
- else
- /* Unknown */
- shutdown_reason = SHUTDOWN_crash;
- app_shutdown(shutdown_reason);
- free(shutdown);
-}
-#endif
-
-
-/* This should be overridden by the application we are linked against. */
-__attribute__((weak)) int app_main(start_info_t *si)
-{
- printk("kernel.c: dummy main: start_info=%p\n", si);
- return 0;
-}
-
-void start_kernel(void)
-{
- /* Set up events. */
- init_events();
-
- /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
- local_irq_enable();
-
- setup_xen_features();
-
- /* Init memory management. */
- init_mm();
-
- /* Init time and timers. */
- init_time();
-
- /* Init the console driver. */
- init_console();
-
- /* Init grant tables */
- init_gnttab();
-
- /* Init scheduler. */
- init_sched();
-
- /* Init XenBus */
- init_xenbus();
-
-#ifdef CONFIG_XENBUS
- create_thread("shutdown", shutdown_thread, NULL);
-#endif
-
- /* Call (possibly overridden) app_main() */
- app_main(&start_info);
-
- /* Everything initialised, start idle thread */
- run_idle_thread();
-}
-
-void stop_kernel(void)
-{
- /* TODO: fs import */
-
- local_irq_disable();
-
- /* Reset grant tables */
- fini_gnttab();
-
- /* Reset XenBus */
- fini_xenbus();
-
- /* Reset timers */
- fini_time();
-
- /* Reset memory management. */
- fini_mm();
-
- /* Reset events. */
- fini_events();
-
- /* Reset arch details */
- arch_fini();
-}
-
-/*
- * do_exit: This is called whenever an IRET fails in entry.S.
- * This will generally be because an application has got itself into
- * a really bad state (probably a bad CS or SS). It must be killed.
- * Of course, minimal OS doesn't have applications :-)
- */
-
-void do_exit(void)
-{
- printk("Do_exit called!\n");
- arch_do_exit();
- for( ;; )
- {
- struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
- }
-}
+++ /dev/null
-#ifndef HAVE_LIBC
-#include <ctype.h>
-
-unsigned char _ctype[] = {
-_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
-_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
-_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
-_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
-_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
-_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
-_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
-_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
-_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
-_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
-_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
-_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
-_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
-_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
-_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
-_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
-_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
-_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
-_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
-_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
-#endif
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: math.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes:
- *
- * Date: Aug 2003
- *
- * Environment: Xen Minimal OS
- * Description: Library functions for 64bit arith and other
- * from freebsd, files in sys/libkern/ (qdivrem.c, etc)
- *
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
-*/
-
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/time.h>
-
-/* XXX RN: Yuck hardcoded endianess :) */
-#define _QUAD_HIGHWORD 1
-#define _QUAD_LOWWORD 0
-
-/*
- * From
- * @(#)quad.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Depending on the desired operation, we view a `long long' (aka quad_t) in
- * one or more of the following formats.
- */
-union uu {
- quad_t q; /* as a (signed) quad */
- quad_t uq; /* as an unsigned quad */
- int32_t sl[2]; /* as two signed longs */
- uint32_t ul[2]; /* as two unsigned longs */
-};
-
-/*
- * Define high and low longwords.
- */
-#define H _QUAD_HIGHWORD
-#define L _QUAD_LOWWORD
-
-/*
- * Total number of bits in an quad_t and in the pieces that make it up.
- * These are used for shifting, and also below for halfword extraction
- * and assembly.
- */
-#ifndef HAVE_LIBC
-#define CHAR_BIT 8 /* number of bits in a char */
-#endif
-#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT)
-#define LONG_BITS (sizeof(int32_t) * CHAR_BIT)
-#define HALF_BITS (sizeof(int32_t) * CHAR_BIT / 2)
-
-/*
- * Extract high and low shortwords from longword, and move low shortword of
- * longword to upper half of int32_t, i.e., produce the upper longword of
- * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be uint32_t.)
- *
- * These are used in the multiply code, to split a longword into upper
- * and lower halves, and to reassemble a product as a quad_t, shifted left
- * (sizeof(int32_t)*CHAR_BIT/2).
- */
-#define HHALF(x) ((x) >> HALF_BITS)
-#define LHALF(x) ((x) & ((1UL << HALF_BITS) - 1))
-#define LHUP(x) ((x) << HALF_BITS)
-
-
-/*
- * From
- * qdivrem.c
- */
-
-/*
- * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
- * section 4.3.1, pp. 257--259.
- */
-#define B (1UL << HALF_BITS) /* digit base */
-
-/* Combine two `digits' to make a single two-digit number. */
-#define COMBINE(a, b) (((uint32_t)(a) << HALF_BITS) | (b))
-
-/* select a type for digits in base B: */
-typedef uint16_t digit;
-
-/*
- * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
- * `fall out' the left (there never will be any such anyway).
- * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
- */
-static void
-shl(register digit *p, register int len, register int sh)
-{
- register int i;
-
- for (i = 0; i < len; i++)
- p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
- p[i] = LHALF(p[i] << sh);
-}
-
-/*
- * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
- *
- * We do this in base 2-sup-HALF_BITS, so that all intermediate products
- * fit within uint32_t. As a consequence, the maximum length dividend and
- * divisor are 4 `digits' in this base (they are shorter if they have
- * leading zeros).
- */
-u_quad_t
-__qdivrem(u_quad_t uq, u_quad_t vq, u_quad_t *arq)
-{
- union uu tmp;
- digit *u, *v, *q;
- register digit v1, v2;
- uint32_t qhat, rhat, t;
- int m, n, d, j, i;
- digit uspace[5], vspace[5], qspace[5];
-
- /*
- * Take care of special cases: divide by zero, and u < v.
- */
- if (vq == 0) {
- /* divide by zero. */
- static volatile const unsigned int zero = 0;
-
- tmp.ul[H] = tmp.ul[L] = 1 / zero;
- if (arq)
- *arq = uq;
- return (tmp.q);
- }
- if (uq < vq) {
- if (arq)
- *arq = uq;
- return (0);
- }
- u = &uspace[0];
- v = &vspace[0];
- q = &qspace[0];
-
- /*
- * Break dividend and divisor into digits in base B, then
- * count leading zeros to determine m and n. When done, we
- * will have:
- * u = (u[1]u[2]...u[m+n]) sub B
- * v = (v[1]v[2]...v[n]) sub B
- * v[1] != 0
- * 1 < n <= 4 (if n = 1, we use a different division algorithm)
- * m >= 0 (otherwise u < v, which we already checked)
- * m + n = 4
- * and thus
- * m = 4 - n <= 2
- */
- tmp.uq = uq;
- u[0] = 0;
- u[1] = HHALF(tmp.ul[H]);
- u[2] = LHALF(tmp.ul[H]);
- u[3] = HHALF(tmp.ul[L]);
- u[4] = LHALF(tmp.ul[L]);
- tmp.uq = vq;
- v[1] = HHALF(tmp.ul[H]);
- v[2] = LHALF(tmp.ul[H]);
- v[3] = HHALF(tmp.ul[L]);
- v[4] = LHALF(tmp.ul[L]);
- for (n = 4; v[1] == 0; v++) {
- if (--n == 1) {
- uint32_t rbj; /* r*B+u[j] (not root boy jim) */
- digit q1, q2, q3, q4;
-
- /*
- * Change of plan, per exercise 16.
- * r = 0;
- * for j = 1..4:
- * q[j] = floor((r*B + u[j]) / v),
- * r = (r*B + u[j]) % v;
- * We unroll this completely here.
- */
- t = v[2]; /* nonzero, by definition */
- q1 = u[1] / t;
- rbj = COMBINE(u[1] % t, u[2]);
- q2 = rbj / t;
- rbj = COMBINE(rbj % t, u[3]);
- q3 = rbj / t;
- rbj = COMBINE(rbj % t, u[4]);
- q4 = rbj / t;
- if (arq)
- *arq = rbj % t;
- tmp.ul[H] = COMBINE(q1, q2);
- tmp.ul[L] = COMBINE(q3, q4);
- return (tmp.q);
- }
- }
-
- /*
- * By adjusting q once we determine m, we can guarantee that
- * there is a complete four-digit quotient at &qspace[1] when
- * we finally stop.
- */
- for (m = 4 - n; u[1] == 0; u++)
- m--;
- for (i = 4 - m; --i >= 0;)
- q[i] = 0;
- q += 4 - m;
-
- /*
- * Here we run Program D, translated from MIX to C and acquiring
- * a few minor changes.
- *
- * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
- */
- d = 0;
- for (t = v[1]; t < B / 2; t <<= 1)
- d++;
- if (d > 0) {
- shl(&u[0], m + n, d); /* u <<= d */
- shl(&v[1], n - 1, d); /* v <<= d */
- }
- /*
- * D2: j = 0.
- */
- j = 0;
- v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
- v2 = v[2]; /* for D3 */
- do {
- register digit uj0, uj1, uj2;
-
- /*
- * D3: Calculate qhat (\^q, in TeX notation).
- * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
- * let rhat = (u[j]*B + u[j+1]) mod v[1].
- * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
- * decrement qhat and increase rhat correspondingly.
- * Note that if rhat >= B, v[2]*qhat < rhat*B.
- */
- uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
- uj1 = u[j + 1]; /* for D3 only */
- uj2 = u[j + 2]; /* for D3 only */
- if (uj0 == v1) {
- qhat = B;
- rhat = uj1;
- goto qhat_too_big;
- } else {
- uint32_t nn = COMBINE(uj0, uj1);
- qhat = nn / v1;
- rhat = nn % v1;
- }
- while (v2 * qhat > COMBINE(rhat, uj2)) {
- qhat_too_big:
- qhat--;
- if ((rhat += v1) >= B)
- break;
- }
- /*
- * D4: Multiply and subtract.
- * The variable `t' holds any borrows across the loop.
- * We split this up so that we do not require v[0] = 0,
- * and to eliminate a final special case.
- */
- for (t = 0, i = n; i > 0; i--) {
- t = u[i + j] - v[i] * qhat - t;
- u[i + j] = LHALF(t);
- t = (B - HHALF(t)) & (B - 1);
- }
- t = u[j] - t;
- u[j] = LHALF(t);
- /*
- * D5: test remainder.
- * There is a borrow if and only if HHALF(t) is nonzero;
- * in that (rare) case, qhat was too large (by exactly 1).
- * Fix it by adding v[1..n] to u[j..j+n].
- */
- if (HHALF(t)) {
- qhat--;
- for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
- t += u[i + j] + v[i];
- u[i + j] = LHALF(t);
- t = HHALF(t);
- }
- u[j] = LHALF(u[j] + t);
- }
- q[j] = qhat;
- } while (++j <= m); /* D7: loop on j. */
-
- /*
- * If caller wants the remainder, we have to calculate it as
- * u[m..m+n] >> d (this is at most n digits and thus fits in
- * u[m+1..m+n], but we may need more source digits).
- */
- if (arq) {
- if (d) {
- for (i = m + n; i > m; --i)
- u[i] = (u[i] >> d) |
- LHALF(u[i - 1] << (HALF_BITS - d));
- u[i] = 0;
- }
- tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
- tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
- *arq = tmp.q;
- }
-
- tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
- tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
- return (tmp.q);
-}
-
-/*
- * From
- * divdi3.c
- */
-
-/*
- * Divide two signed quads.
- * ??? if -1/2 should produce -1 on this machine, this code is wrong
- */
-quad_t
-__divdi3(quad_t a, quad_t b)
-{
- u_quad_t ua, ub, uq;
- int neg;
-
- if (a < 0)
- ua = -(u_quad_t)a, neg = 1;
- else
- ua = a, neg = 0;
- if (b < 0)
- ub = -(u_quad_t)b, neg ^= 1;
- else
- ub = b;
- uq = __qdivrem(ua, ub, (u_quad_t *)0);
- return (neg ? -uq : uq);
-}
-
-/*
- * From
- * udivdi3.c
- */
-
-/*
- * Divide two unsigned quads.
- */
-u_quad_t
-__udivdi3(u_quad_t a, u_quad_t b)
-{
- return (__qdivrem(a, b, (u_quad_t *)0));
-}
-
-/*
- * From
- * umoddi3.c
- */
-
-/*
- * Return remainder after dividing two unsigned quads.
- */
-u_quad_t
-__umoddi3(u_quad_t a, u_quad_t b)
-{
- u_quad_t r;
-
- (void)__qdivrem(a, b, &r);
- return (r);
-}
-
-/*
- * From
- * moddi3.c
- */
-
-/*
- * Return remainder after dividing two signed quads.
- *
- * XXX
- * If -1/2 should produce -1 on this machine, this code is wrong.
- */
-quad_t
-__moddi3(quad_t a, quad_t b)
-{
- u_quad_t ua, ub, ur;
- int neg;
-
- if (a < 0)
- ua = -(u_quad_t)a, neg = 1;
- else
- ua = a, neg = 0;
- if (b < 0)
- ub = -(u_quad_t)b;
- else
- ub = b;
- (void)__qdivrem(ua, ub, &ur);
- return (neg ? -ur : ur);
-}
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: printf.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: Aug 2003, Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: Library functions for printing
- * (Linux port, mainly lib/vsprintf.c)
- *
- ****************************************************************************
- */
-
-/*
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
-/*
- * Wirzenius wrote this portably, Torvalds fucked it up :-)
- */
-
-/*
- * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
- * - changed to provide snprintf and vsnprintf functions
- * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
- * - scnprintf and vscnprintf
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined HAVE_LIBC
-
-#include <mini-os/os.h>
-#include <mini-os/types.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/lib.h>
-#include <mini-os/mm.h>
-#include <mini-os/ctype.h>
-#include <mini-os/posix/limits.h>
-
-/**
- * simple_strtoul - convert a string to an unsigned long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
- unsigned long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- }
- while (isxdigit(*cp) &&
- (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-/**
- * simple_strtol - convert a string to a signed long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long simple_strtol(const char *cp,char **endp,unsigned int base)
-{
- if(*cp=='-')
- return -simple_strtoul(cp+1,endp,base);
- return simple_strtoul(cp,endp,base);
-}
-
-/**
- * simple_strtoull - convert a string to an unsigned long long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
-{
- unsigned long long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- }
- while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
- ? toupper(*cp) : *cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-/**
- * simple_strtoll - convert a string to a signed long long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long long simple_strtoll(const char *cp,char **endp,unsigned int base)
-{
- if(*cp=='-')
- return -simple_strtoull(cp+1,endp,base);
- return simple_strtoull(cp,endp,base);
-}
-
-static int skip_atoi(const char **s)
-{
- int i=0;
-
- while (isdigit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
-{
- char c,sign,tmp[66];
- const char *digits;
- const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int i;
-
- digits = (type & LARGE) ? large_digits : small_digits;
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
- return buf;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if (num < 0) {
- sign = '-';
- num = -num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else
- {
- /* XXX KAF: force unsigned mod and div. */
- unsigned long long num2=(unsigned long long)num;
- unsigned int base2=(unsigned int)base;
- while (num2 != 0) { tmp[i++] = digits[num2%base2]; num2 /= base2; }
- }
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(ZEROPAD+LEFT))) {
- while(size-->0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- }
- if (sign) {
- if (buf <= end)
- *buf = sign;
- ++buf;
- }
- if (type & SPECIAL) {
- if (base==8) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- } else if (base==16) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- if (buf <= end)
- *buf = digits[33];
- ++buf;
- }
- }
- if (!(type & LEFT)) {
- while (size-- > 0) {
- if (buf <= end)
- *buf = c;
- ++buf;
- }
- }
- while (i < precision--) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- }
- while (i-- > 0) {
- if (buf <= end)
- *buf = tmp[i];
- ++buf;
- }
- while (size-- > 0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- return buf;
-}
-
-/**
-* vsnprintf - Format a string and place it in a buffer
-* @buf: The buffer to place the result into
-* @size: The size of the buffer, including the trailing null space
-* @fmt: The format string to use
-* @args: Arguments for the format string
-*
-* Call this function if you are already dealing with a va_list.
-* You probably want snprintf instead.
- */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int len;
- unsigned long long num;
- int i, base;
- char *str, *end, c;
- const char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
-
- str = buf;
- end = buf + size - 1;
-
- if (end < buf - 1) {
- end = ((void *) -1);
- size = end - buf + 1;
- }
-
- for (; *fmt ; ++fmt) {
- if (*fmt != '%') {
- if (str <= end)
- *str = *fmt;
- ++str;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (isdigit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
- qualifier = *fmt;
- ++fmt;
- if (qualifier == 'l' && *fmt == 'l') {
- qualifier = 'L';
- ++fmt;
- }
- }
- if (*fmt == 'q') {
- qualifier = 'L';
- ++fmt;
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT)) {
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- c = (unsigned char) va_arg(args, int);
- if (str <= end)
- *str = c;
- ++str;
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (!s)
- s = "<NULL>";
-
- len = strnlen(s, precision);
-
- if (!(flags & LEFT)) {
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- for (i = 0; i < len; ++i) {
- if (str <= end)
- *str = *s;
- ++str; ++s;
- }
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
- }
- str = number(str, end,
- (unsigned long) va_arg(args, void *),
- 16, field_width, precision, flags);
- continue;
-
-
- case 'n':
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- case '%':
- if (str <= end)
- *str = '%';
- ++str;
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
-
- default:
- if (str <= end)
- *str = '%';
- ++str;
- if (*fmt) {
- if (str <= end)
- *str = *fmt;
- ++str;
- } else {
- --fmt;
- }
- continue;
- }
- if (qualifier == 'L')
- num = va_arg(args, long long);
- else if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & SIGN)
- num = (signed int) num;
- }
-
- str = number(str, end, num, base,
- field_width, precision, flags);
- }
- if (str <= end)
- *str = '\0';
- else if (size > 0)
- /* don't write out a null byte if the buf size is zero */
- *end = '\0';
- /* the trailing null byte doesn't count towards the total
- * ++str;
- */
- return str-buf;
-}
-
-/**
- * snprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- */
-int snprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsnprintf(buf,size,fmt,args);
- va_end(args);
- return i;
-}
-
-/**
- * vsprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want sprintf instead.
- */
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
- return vsnprintf(buf, 0xFFFFFFFFUL, fmt, args);
-}
-
-
-/**
- * sprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @...: Arguments for the format string
- */
-int sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsprintf(buf,fmt,args);
- va_end(args);
- return i;
-}
-
-/**
- * vsscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: format of buffer
- * @args: arguments
- */
-int vsscanf(const char * buf, const char * fmt, va_list args)
-{
- const char *str = buf;
- char *next;
- char digit;
- int num = 0;
- int qualifier;
- int base;
- int field_width;
- int is_sign = 0;
-
- while(*fmt && *str) {
- /* skip any white space in format */
- /* white space in format matchs any amount of
- * white space, including none, in the input.
- */
- if (isspace(*fmt)) {
- while (isspace(*fmt))
- ++fmt;
- while (isspace(*str))
- ++str;
- }
-
- /* anything that is not a conversion must match exactly */
- if (*fmt != '%' && *fmt) {
- if (*fmt++ != *str++)
- break;
- continue;
- }
-
- if (!*fmt)
- break;
- ++fmt;
-
- /* skip this conversion.
- * advance both strings to next white space
- */
- if (*fmt == '*') {
- while (!isspace(*fmt) && *fmt)
- fmt++;
- while (!isspace(*str) && *str)
- str++;
- continue;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
-
- /* get conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
- *fmt == 'Z' || *fmt == 'z') {
- qualifier = *fmt++;
- if (unlikely(qualifier == *fmt)) {
- if (qualifier == 'h') {
- qualifier = 'H';
- fmt++;
- } else if (qualifier == 'l') {
- qualifier = 'L';
- fmt++;
- }
- }
- }
- base = 10;
- is_sign = 0;
-
- if (!*fmt || !*str)
- break;
-
- switch(*fmt++) {
- case 'c':
- {
- char *s = (char *) va_arg(args,char*);
- if (field_width == -1)
- field_width = 1;
- do {
- *s++ = *str++;
- } while (--field_width > 0 && *str);
- num++;
- }
- continue;
- case 's':
- {
- char *s = (char *) va_arg(args, char *);
- if(field_width == -1)
- field_width = INT_MAX;
- /* first, skip leading white space in buffer */
- while (isspace(*str))
- str++;
-
- /* now copy until next white space */
- while (*str && !isspace(*str) && field_width--) {
- *s++ = *str++;
- }
- *s = '\0';
- num++;
- }
- continue;
- case 'n':
- /* return number of characters read so far */
- {
- int *i = (int *)va_arg(args,int*);
- *i = str - buf;
- }
- continue;
- case 'o':
- base = 8;
- break;
- case 'x':
- case 'X':
- base = 16;
- break;
- case 'i':
- base = 0;
- case 'd':
- is_sign = 1;
- case 'u':
- break;
- case '%':
- /* looking for '%' in str */
- if (*str++ != '%')
- return num;
- continue;
- default:
- /* invalid format; stop here */
- return num;
- }
-
- /* have some sort of integer conversion.
- * first, skip white space in buffer.
- */
- while (isspace(*str))
- str++;
-
- digit = *str;
- if (is_sign && digit == '-')
- digit = *(str + 1);
-
- if (!digit
- || (base == 16 && !isxdigit(digit))
- || (base == 10 && !isdigit(digit))
- || (base == 8 && (!isdigit(digit) || digit > '7'))
- || (base == 0 && !isdigit(digit)))
- break;
-
- switch(qualifier) {
- case 'H': /* that's 'hh' in format */
- if (is_sign) {
- signed char *s = (signed char *) va_arg(args,signed char *);
- *s = (signed char) simple_strtol(str,&next,base);
- } else {
- unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
- *s = (unsigned char) simple_strtoul(str, &next, base);
- }
- break;
- case 'h':
- if (is_sign) {
- short *s = (short *) va_arg(args,short *);
- *s = (short) simple_strtol(str,&next,base);
- } else {
- unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
- *s = (unsigned short) simple_strtoul(str, &next, base);
- }
- break;
- case 'l':
- if (is_sign) {
- long *l = (long *) va_arg(args,long *);
- *l = simple_strtol(str,&next,base);
- } else {
- unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
- *l = simple_strtoul(str,&next,base);
- }
- break;
- case 'L':
- if (is_sign) {
- long long *l = (long long*) va_arg(args,long long *);
- *l = simple_strtoll(str,&next,base);
- } else {
- unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
- *l = simple_strtoull(str,&next,base);
- }
- break;
- case 'Z':
- case 'z':
- {
- size_t *s = (size_t*) va_arg(args,size_t*);
- *s = (size_t) simple_strtoul(str,&next,base);
- }
- break;
- default:
- if (is_sign) {
- int *i = (int *) va_arg(args, int*);
- *i = (int) simple_strtol(str,&next,base);
- } else {
- unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
- *i = (unsigned int) simple_strtoul(str,&next,base);
- }
- break;
- }
- num++;
-
- if (!next)
- break;
- str = next;
- }
- return num;
-}
-
-/**
- * sscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: formatting of buffer
- * @...: resulting arguments
- */
-int sscanf(const char * buf, const char * fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args,fmt);
- i = vsscanf(buf,fmt,args);
- va_end(args);
- return i;
-}
-
-#endif
+++ /dev/null
-#include <mini-os/kernel.h>
-#include <mini-os/console.h>
-
-void __stack_chk_fail(void)
-{
- printk("stack smashing detected\n");
- do_exit();
-}
+++ /dev/null
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- * File: string.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes:
- *
- * Date: Aug 2003
- *
- * Environment: Xen Minimal OS
- * Description: Library function for string and memory manipulation
- * Origin unknown
- *
- ****************************************************************************
- * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
- ****************************************************************************
- */
-
-#include <strings.h>
-
-/* newlib defines ffs but not ffsll or ffsl */
-int __ffsti2 (long long int lli)
-{
- int i, num, t, tmpint, len;
-
- num = sizeof(long long int) / sizeof(int);
- if (num == 1) return (ffs((int) lli));
- len = sizeof(int) * 8;
-
- for (i = 0; i < num; i++) {
- tmpint = (int) (((lli >> len) << len) ^ lli);
-
- t = ffs(tmpint);
- if (t)
- return (t + i * len);
- lli = lli >> len;
- }
- return 0;
-}
-
-int __ffsdi2 (long int li)
-{
- return __ffsti2 ((long long int) li);
-}
-
-int ffsl (long int li)
-{
- return __ffsti2 ((long long int) li);
-}
-
-int ffsll (long long int lli)
-{
- return __ffsti2 (lli);
-}
-
-#if !defined HAVE_LIBC
-
-#include <mini-os/os.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-
-int memcmp(const void * cs,const void * ct,size_t count)
-{
- const unsigned char *su1, *su2;
- signed char res = 0;
-
- for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
- if ((res = *su1 - *su2) != 0)
- break;
- return res;
-}
-
-void * memcpy(void * dest,const void *src,size_t count)
-{
- char *tmp = (char *) dest;
- const char *s = src;
-
- while (count--)
- *tmp++ = *s++;
-
- return dest;
-}
-
-int strncmp(const char * cs,const char * ct,size_t count)
-{
- register signed char __res = 0;
-
- while (count) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
- count--;
- }
-
- return __res;
-}
-
-int strcmp(const char * cs,const char * ct)
-{
- register signed char __res;
-
- while (1) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
- }
-
- return __res;
-}
-
-char * strcpy(char * dest,const char *src)
-{
- char *tmp = dest;
-
- while ((*dest++ = *src++) != '\0')
- /* nothing */;
- return tmp;
-}
-
-char * strncpy(char * dest,const char *src,size_t count)
-{
- char *tmp = dest;
-
- while (count-- && (*dest++ = *src++) != '\0')
- /* nothing */;
-
- return tmp;
-}
-
-void * memset(void * s,int c,size_t count)
-{
- char *xs = (char *) s;
-
- while (count--)
- *xs++ = c;
-
- return s;
-}
-
-size_t strnlen(const char * s, size_t count)
-{
- const char *sc;
-
- for (sc = s; count-- && *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
-}
-
-
-char * strcat(char * dest, const char * src)
-{
- char *tmp = dest;
-
- while (*dest)
- dest++;
-
- while ((*dest++ = *src++) != '\0');
-
- return tmp;
-}
-
-size_t strlen(const char * s)
-{
- const char *sc;
-
- for (sc = s; *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
-}
-
-char * strchr(const char * s, int c)
-{
- for(; *s != (char) c; ++s)
- if (*s == '\0')
- return NULL;
- return (char *)s;
-}
-
-char * strrchr(const char * s, int c)
-{
- const char *res = NULL;
- for(; *s != '\0'; ++s)
- if (*s == (char) c)
- res = s;
- return (char *)res;
-}
-
-char * strstr(const char * s1,const char * s2)
-{
- int l1, l2;
-
- l2 = strlen(s2);
- if (!l2)
- return (char *) s1;
- l1 = strlen(s1);
- while (l1 >= l2) {
- l1--;
- if (!memcmp(s1,s2,l2))
- return (char *) s1;
- s1++;
- }
- return NULL;
-}
-
-char *strdup(const char *x)
-{
- int l = strlen(x);
- char *res = malloc(l + 1);
- if (!res) return NULL;
- memcpy(res, x, l + 1);
- return res;
-}
-
-int ffs(int i)
-{
- int c = 1;
-
- do {
- if (i & 1)
- return (c);
- i = i >> 1;
- c++;
- } while (i);
- return 0;
-}
-
-#endif
+++ /dev/null
-/*
- * POSIX-compatible libc layer
- *
- * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
- *
- * Provides the UNIXish part of the standard libc function.
- *
- * Relatively straight-forward: just multiplex the file descriptor operations
- * among the various file types (console, FS, network, ...)
- */
-
-//#define LIBC_VERBOSE
-//#define LIBC_DEBUG
-
-#ifdef LIBC_DEBUG
-#define DEBUG(fmt,...) printk(fmt, ##__VA_ARGS__)
-#else
-#define DEBUG(fmt,...)
-#endif
-
-#ifdef HAVE_LIBC
-#include <os.h>
-#include <console.h>
-#include <sched.h>
-#include <events.h>
-#include <wait.h>
-#include <netfront.h>
-#include <blkfront.h>
-#include <fbfront.h>
-#include <tpmfront.h>
-#include <tpm_tis.h>
-#include <xenbus.h>
-#include <xenstore.h>
-#include <poll.h>
-
-#include <sys/types.h>
-#include <sys/unistd.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <net/if.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <assert.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <math.h>
-
-#ifdef HAVE_LWIP
-#include <lwip/sockets.h>
-#endif
-
-#define debug(fmt, ...) \
-
-#define print_unsupported(fmt, ...) \
- printk("Unsupported function "fmt" called in Mini-OS kernel\n", ## __VA_ARGS__);
-
-/* Crash on function call */
-#define unsupported_function_crash(function) \
- int __unsup_##function(void) asm(#function); \
- int __unsup_##function(void) \
- { \
- print_unsupported(#function); \
- do_exit(); \
- }
-
-/* Log and err out on function call */
-#define unsupported_function_log(type, function, ret) \
- type __unsup_##function(void) asm(#function); \
- type __unsup_##function(void) \
- { \
- print_unsupported(#function); \
- errno = ENOSYS; \
- return ret; \
- }
-
-/* Err out on function call */
-#define unsupported_function(type, function, ret) \
- type __unsup_##function(void) asm(#function); \
- type __unsup_##function(void) \
- { \
- errno = ENOSYS; \
- return ret; \
- }
-
-#define NOFILE 32
-extern void minios_interface_close_fd(int fd);
-extern void minios_evtchn_close_fd(int fd);
-extern void minios_gnttab_close_fd(int fd);
-
-pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
-struct file files[NOFILE] = {
- { .type = FTYPE_CONSOLE }, /* stdin */
- { .type = FTYPE_CONSOLE }, /* stdout */
- { .type = FTYPE_CONSOLE }, /* stderr */
-};
-
-DECLARE_WAIT_QUEUE_HEAD(event_queue);
-
-int alloc_fd(enum fd_type type)
-{
- int i;
- pthread_mutex_lock(&fd_lock);
- for (i=0; i<NOFILE; i++) {
- if (files[i].type == FTYPE_NONE) {
- files[i].type = type;
- pthread_mutex_unlock(&fd_lock);
- return i;
- }
- }
- pthread_mutex_unlock(&fd_lock);
- printk("Too many opened files\n");
- do_exit();
-}
-
-void close_all_files(void)
-{
- int i;
- pthread_mutex_lock(&fd_lock);
- for (i=NOFILE - 1; i > 0; i--)
- if (files[i].type != FTYPE_NONE)
- close(i);
- pthread_mutex_unlock(&fd_lock);
-}
-
-int dup2(int oldfd, int newfd)
-{
- pthread_mutex_lock(&fd_lock);
- if (files[newfd].type != FTYPE_NONE)
- close(newfd);
- // XXX: this is a bit bogus, as we are supposed to share the offset etc
- files[newfd] = files[oldfd];
- pthread_mutex_unlock(&fd_lock);
- return 0;
-}
-
-pid_t getpid(void)
-{
- return 1;
-}
-
-pid_t getppid(void)
-{
- return 1;
-}
-
-pid_t setsid(void)
-{
- return 1;
-}
-
-char *getcwd(char *buf, size_t size)
-{
- snprintf(buf, size, "/");
- return buf;
-}
-
-#define LOG_PATH "/var/log/"
-#define SAVE_PATH "/var/lib/xen"
-#define SAVE_CONSOLE 1
-#define RESTORE_CONSOLE 2
-
-int mkdir(const char *pathname, mode_t mode)
-{
- errno = EIO;
- return -1;
-}
-
-#ifdef CONFIG_CONSFRONT
-int posix_openpt(int flags)
-{
- struct consfront_dev *dev;
-
- /* Ignore flags */
-
- dev = init_consfront(NULL);
- dev->fd = alloc_fd(FTYPE_CONSOLE);
- files[dev->fd].cons.dev = dev;
-
- printk("fd(%d) = posix_openpt\n", dev->fd);
- return(dev->fd);
-}
-
-int open_savefile(const char *path, int save)
-{
- struct consfront_dev *dev;
- char nodename[64];
-
- snprintf(nodename, sizeof(nodename), "device/console/%d", save ? SAVE_CONSOLE : RESTORE_CONSOLE);
-
- dev = init_consfront(nodename);
- dev->fd = alloc_fd(FTYPE_SAVEFILE);
- files[dev->fd].cons.dev = dev;
-
- printk("fd(%d) = open_savefile\n", dev->fd);
- return(dev->fd);
-}
-#else
-int posix_openpt(int flags)
-{
- errno = EIO;
- return -1;
-}
-int open_savefile(const char *path, int save)
-{
- errno = EIO;
- return -1;
-}
-#endif
-
-int open(const char *pathname, int flags, ...)
-{
- int fd;
- /* Ugly, but fine. */
- if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) {
- fd = alloc_fd(FTYPE_CONSOLE);
- printk("open(%s) -> %d\n", pathname, fd);
- return fd;
- }
- if (!strncmp(pathname, "/dev/mem", strlen("/dev/mem"))) {
- fd = alloc_fd(FTYPE_MEM);
- printk("open(/dev/mem) -> %d\n", fd);
- return fd;
- }
- if (!strncmp(pathname, "/dev/ptmx", strlen("/dev/ptmx")))
- return posix_openpt(flags);
- if (!strncmp(pathname,SAVE_PATH,strlen(SAVE_PATH)))
- return open_savefile(pathname, flags & O_WRONLY);
- errno = EIO;
- return -1;
-}
-
-int isatty(int fd)
-{
- return files[fd].type == FTYPE_CONSOLE;
-}
-
-int read(int fd, void *buf, size_t nbytes)
-{
- switch (files[fd].type) {
- case FTYPE_SAVEFILE:
- case FTYPE_CONSOLE: {
- int ret;
- DEFINE_WAIT(w);
- while(1) {
- add_waiter(w, console_queue);
- ret = xencons_ring_recv(files[fd].cons.dev, buf, nbytes);
- if (ret)
- break;
- schedule();
- }
- remove_waiter(w, console_queue);
- return ret;
- }
-#ifdef HAVE_LWIP
- case FTYPE_SOCKET:
- return lwip_read(files[fd].socket.fd, buf, nbytes);
-#endif
-#ifdef CONFIG_NETFRONT
- case FTYPE_TAP: {
- ssize_t ret;
- ret = netfront_receive(files[fd].tap.dev, buf, nbytes);
- if (ret <= 0) {
- errno = EAGAIN;
- return -1;
- }
- return ret;
- }
-#endif
-#ifdef CONFIG_KBDFRONT
- case FTYPE_KBD: {
- int ret, n;
- n = nbytes / sizeof(union xenkbd_in_event);
- ret = kbdfront_receive(files[fd].kbd.dev, buf, n);
- if (ret <= 0) {
- errno = EAGAIN;
- return -1;
- }
- return ret * sizeof(union xenkbd_in_event);
- }
-#endif
-#ifdef CONFIG_FBFRONT
- case FTYPE_FB: {
- int ret, n;
- n = nbytes / sizeof(union xenfb_in_event);
- ret = fbfront_receive(files[fd].fb.dev, buf, n);
- if (ret <= 0) {
- errno = EAGAIN;
- return -1;
- }
- return ret * sizeof(union xenfb_in_event);
- }
-#endif
-#ifdef CONFIG_BLKFRONT
- case FTYPE_BLK: {
- return blkfront_posix_read(fd, buf, nbytes);
- }
-#endif
-#ifdef CONFIG_TPMFRONT
- case FTYPE_TPMFRONT: {
- return tpmfront_posix_read(fd, buf, nbytes);
- }
-#endif
-#ifdef CONFIG_TPM_TIS
- case FTYPE_TPM_TIS: {
- return tpm_tis_posix_read(fd, buf, nbytes);
- }
-#endif
- default:
- break;
- }
- printk("read(%d): Bad descriptor\n", fd);
- errno = EBADF;
- return -1;
-}
-
-int write(int fd, const void *buf, size_t nbytes)
-{
- switch (files[fd].type) {
- case FTYPE_SAVEFILE: {
- int ret = 0, tot = nbytes;
- while (nbytes > 0) {
- ret = xencons_ring_send(files[fd].cons.dev, (char *)buf, nbytes);
- nbytes -= ret;
- buf = (char *)buf + ret;
- }
- return tot - nbytes;
- }
- case FTYPE_CONSOLE:
- console_print(files[fd].cons.dev, (char *)buf, nbytes);
- return nbytes;
-#ifdef HAVE_LWIP
- case FTYPE_SOCKET:
- return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
-#endif
-#ifdef CONFIG_NETFRONT
- case FTYPE_TAP:
- netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
- return nbytes;
-#endif
-#ifdef CONFIG_BLKFRONT
- case FTYPE_BLK:
- return blkfront_posix_write(fd, buf, nbytes);
-#endif
-#ifdef CONFIG_TPMFRONT
- case FTYPE_TPMFRONT:
- return tpmfront_posix_write(fd, buf, nbytes);
-#endif
-#ifdef CONFIG_TPM_TIS
- case FTYPE_TPM_TIS:
- return tpm_tis_posix_write(fd, buf, nbytes);
-#endif
- default:
- break;
- }
- printk("write(%d): Bad descriptor\n", fd);
- errno = EBADF;
- return -1;
-}
-
-off_t lseek(int fd, off_t offset, int whence)
-{
- off_t* target = NULL;
- switch(files[fd].type) {
-#ifdef CONFIG_BLKFRONT
- case FTYPE_BLK:
- target = &files[fd].blk.offset;
- break;
-#endif
-#ifdef CONFIG_TPMFRONT
- case FTYPE_TPMFRONT:
- target = &files[fd].tpmfront.offset;
- break;
-#endif
-#ifdef CONFIG_TPM_TIS
- case FTYPE_TPM_TIS:
- target = &files[fd].tpm_tis.offset;
- break;
-#endif
- case FTYPE_FILE:
- target = &files[fd].file.offset;
- break;
- default:
- /* Not implemented for this filetype */
- errno = ESPIPE;
- return (off_t) -1;
- }
-
- switch (whence) {
- case SEEK_SET:
- *target = offset;
- break;
- case SEEK_CUR:
- *target += offset;
- break;
- case SEEK_END:
- {
- struct stat st;
- int ret;
- ret = fstat(fd, &st);
- if (ret)
- return -1;
- *target = st.st_size + offset;
- break;
- }
- default:
- errno = EINVAL;
- return -1;
- }
- return *target;
-}
-
-int fsync(int fd) {
- errno = EBADF;
- return -1;
-}
-
-int close(int fd)
-{
- printk("close(%d)\n", fd);
- switch (files[fd].type) {
- default:
- files[fd].type = FTYPE_NONE;
- return 0;
-#ifdef CONFIG_XENBUS
- case FTYPE_XENBUS:
- xs_daemon_close((void*)(intptr_t) fd);
- return 0;
-#endif
-#ifdef HAVE_LWIP
- case FTYPE_SOCKET: {
- int res = lwip_close(files[fd].socket.fd);
- files[fd].type = FTYPE_NONE;
- return res;
- }
-#endif
-#ifdef CONFIG_XC
- case FTYPE_XC:
- minios_interface_close_fd(fd);
- return 0;
- case FTYPE_EVTCHN:
- minios_evtchn_close_fd(fd);
- return 0;
- case FTYPE_GNTMAP:
- minios_gnttab_close_fd(fd);
- return 0;
-#endif
-#ifdef CONFIG_NETFRONT
- case FTYPE_TAP:
- shutdown_netfront(files[fd].tap.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_BLKFRONT
- case FTYPE_BLK:
- shutdown_blkfront(files[fd].blk.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_TPMFRONT
- case FTYPE_TPMFRONT:
- shutdown_tpmfront(files[fd].tpmfront.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_TPM_TIS
- case FTYPE_TPM_TIS:
- shutdown_tpm_tis(files[fd].tpm_tis.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_KBDFRONT
- case FTYPE_KBD:
- shutdown_kbdfront(files[fd].kbd.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_FBFRONT
- case FTYPE_FB:
- shutdown_fbfront(files[fd].fb.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
-#ifdef CONFIG_CONSFRONT
- case FTYPE_SAVEFILE:
- case FTYPE_CONSOLE:
- fini_console(files[fd].cons.dev);
- files[fd].type = FTYPE_NONE;
- return 0;
-#endif
- case FTYPE_NONE:
- break;
- }
- printk("close(%d): Bad descriptor\n", fd);
- errno = EBADF;
- return -1;
-}
-
-static void init_stat(struct stat *buf)
-{
- memset(buf, 0, sizeof(*buf));
- buf->st_dev = 0;
- buf->st_ino = 0;
- buf->st_nlink = 1;
- buf->st_rdev = 0;
- buf->st_blksize = 4096;
- buf->st_blocks = 0;
-}
-
-int stat(const char *path, struct stat *buf)
-{
- errno = EIO;
- return -1;
-}
-
-int fstat(int fd, struct stat *buf)
-{
- init_stat(buf);
- switch (files[fd].type) {
- case FTYPE_SAVEFILE:
- case FTYPE_CONSOLE:
- case FTYPE_SOCKET: {
- if (files[fd].type == FTYPE_CONSOLE)
- buf->st_mode = S_IFCHR|S_IRUSR|S_IWUSR;
- else if (files[fd].type == FTYPE_SOCKET)
- buf->st_mode = S_IFSOCK|S_IRUSR|S_IWUSR;
- else if (files[fd].type == FTYPE_SAVEFILE)
- buf->st_mode = S_IFREG|S_IRUSR|S_IWUSR;
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_size = 0;
- buf->st_atime =
- buf->st_mtime =
- buf->st_ctime = time(NULL);
- return 0;
- }
-#ifdef CONFIG_BLKFRONT
- case FTYPE_BLK:
- return blkfront_posix_fstat(fd, buf);
-#endif
-#ifdef CONFIG_TPMFRONT
- case FTYPE_TPMFRONT:
- return tpmfront_posix_fstat(fd, buf);
-#endif
-#ifdef CONFIG_TPM_TIS
- case FTYPE_TPM_TIS:
- return tpm_tis_posix_fstat(fd, buf);
-#endif
- default:
- break;
- }
-
- printk("statf(%d): Bad descriptor\n", fd);
- errno = EBADF;
- return -1;
-}
-
-int ftruncate(int fd, off_t length)
-{
- errno = EBADF;
- return -1;
-}
-
-int remove(const char *pathname)
-{
- errno = EIO;
- return -1;
-}
-
-int unlink(const char *pathname)
-{
- return remove(pathname);
-}
-
-int rmdir(const char *pathname)
-{
- return remove(pathname);
-}
-
-int fcntl(int fd, int cmd, ...)
-{
- long arg;
- va_list ap;
- va_start(ap, cmd);
- arg = va_arg(ap, long);
- va_end(ap);
-
- switch (cmd) {
-#ifdef HAVE_LWIP
- case F_SETFL:
- if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) {
- /* Only flag supported: non-blocking mode */
- uint32_t nblock = !!(arg & O_NONBLOCK);
- return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock);
- }
- /* Fallthrough */
-#endif
- default:
- printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg);
- errno = ENOSYS;
- return -1;
- }
-}
-
-DIR *opendir(const char *name)
-{
- DIR *ret;
- ret = malloc(sizeof(*ret));
- ret->name = strdup(name);
- ret->offset = 0;
- ret->entries = NULL;
- ret->curentry = -1;
- ret->nbentries = 0;
- ret->has_more = 1;
- return ret;
-}
-
-struct dirent *readdir(DIR *dir)
-{
- return NULL;
-}
-
-int closedir(DIR *dir)
-{
- int i;
- for (i=0; i<dir->nbentries; i++)
- free(dir->entries[i]);
- free(dir->entries);
- free(dir->name);
- free(dir);
- return 0;
-}
-
-/* We assume that only the main thread calls select(). */
-
-static const char file_types[] = {
- [FTYPE_NONE] = 'N',
- [FTYPE_CONSOLE] = 'C',
- [FTYPE_XENBUS] = 'S',
- [FTYPE_XC] = 'X',
- [FTYPE_EVTCHN] = 'E',
- [FTYPE_SOCKET] = 's',
- [FTYPE_TAP] = 'T',
- [FTYPE_BLK] = 'B',
- [FTYPE_KBD] = 'K',
- [FTYPE_FB] = 'G',
-};
-#ifdef LIBC_DEBUG
-static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
-{
- int i, comma;
-#define printfds(set) do {\
- comma = 0; \
- for (i = 0; i < nfds; i++) { \
- if (FD_ISSET(i, set)) { \
- if (comma) \
- printk(", "); \
- printk("%d(%c)", i, file_types[files[i].type]); \
- comma = 1; \
- } \
- } \
-} while (0)
-
- printk("[");
- if (readfds)
- printfds(readfds);
- printk("], [");
- if (writefds)
- printfds(writefds);
- printk("], [");
- if (exceptfds)
- printfds(exceptfds);
- printk("], ");
- if (timeout)
- printk("{ %ld, %ld }", timeout->tv_sec, timeout->tv_usec);
-}
-#else
-#define dump_set(nfds, readfds, writefds, exceptfds, timeout)
-#endif
-
-#ifdef LIBC_DEBUG
-static void dump_pollfds(struct pollfd *pfd, int nfds, int timeout)
-{
- int i, comma, fd;
-
- printk("[");
- comma = 0;
- for (i = 0; i < nfds; i++) {
- fd = pfd[i].fd;
- if (comma)
- printk(", ");
- printk("%d(%c)/%02x", fd, file_types[files[fd].type],
- pfd[i].events);
- comma = 1;
- }
- printk("]");
-
- printk(", %d, %d", nfds, timeout);
-}
-#else
-#define dump_pollfds(pfds, nfds, timeout)
-#endif
-
-/* Just poll without blocking */
-static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
-{
- int i, n = 0;
-#ifdef HAVE_LWIP
- int sock_n = 0, sock_nfds = 0;
- fd_set sock_readfds, sock_writefds, sock_exceptfds;
- struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
-#endif
-
-#ifdef LIBC_VERBOSE
- static int nb;
- static int nbread[NOFILE], nbwrite[NOFILE], nbexcept[NOFILE];
- static s_time_t lastshown;
-
- nb++;
-#endif
-
-#ifdef HAVE_LWIP
- /* first poll network */
- FD_ZERO(&sock_readfds);
- FD_ZERO(&sock_writefds);
- FD_ZERO(&sock_exceptfds);
- for (i = 0; i < nfds; i++) {
- if (files[i].type == FTYPE_SOCKET) {
- if (FD_ISSET(i, readfds)) {
- FD_SET(files[i].socket.fd, &sock_readfds);
- sock_nfds = i+1;
- }
- if (FD_ISSET(i, writefds)) {
- FD_SET(files[i].socket.fd, &sock_writefds);
- sock_nfds = i+1;
- }
- if (FD_ISSET(i, exceptfds)) {
- FD_SET(files[i].socket.fd, &sock_exceptfds);
- sock_nfds = i+1;
- }
- }
- }
- if (sock_nfds > 0) {
- DEBUG("lwip_select(");
- dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
- DEBUG("); -> ");
- sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
- dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
- DEBUG("\n");
- }
-#endif
-
- /* Then see others as well. */
- for (i = 0; i < nfds; i++) {
- switch(files[i].type) {
- default:
- if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
- printk("bogus fd %d in select\n", i);
- /* Fallthrough. */
- case FTYPE_CONSOLE:
- if (FD_ISSET(i, readfds)) {
- if (xencons_ring_avail(files[i].cons.dev))
- n++;
- else
- FD_CLR(i, readfds);
- }
- if (FD_ISSET(i, writefds))
- n++;
- FD_CLR(i, exceptfds);
- break;
-#ifdef CONFIG_XENBUS
- case FTYPE_XENBUS:
- if (FD_ISSET(i, readfds)) {
- if (files[i].xenbus.events)
- n++;
- else
- FD_CLR(i, readfds);
- }
- FD_CLR(i, writefds);
- FD_CLR(i, exceptfds);
- break;
-#endif
- case FTYPE_EVTCHN:
- case FTYPE_TAP:
- case FTYPE_BLK:
- case FTYPE_KBD:
- case FTYPE_FB:
- if (FD_ISSET(i, readfds)) {
- if (files[i].read)
- n++;
- else
- FD_CLR(i, readfds);
- }
- FD_CLR(i, writefds);
- FD_CLR(i, exceptfds);
- break;
-#ifdef HAVE_LWIP
- case FTYPE_SOCKET:
- if (FD_ISSET(i, readfds)) {
- /* Optimize no-network-packet case. */
- if (sock_n && FD_ISSET(files[i].socket.fd, &sock_readfds))
- n++;
- else
- FD_CLR(i, readfds);
- }
- if (FD_ISSET(i, writefds)) {
- if (sock_n && FD_ISSET(files[i].socket.fd, &sock_writefds))
- n++;
- else
- FD_CLR(i, writefds);
- }
- if (FD_ISSET(i, exceptfds)) {
- if (sock_n && FD_ISSET(files[i].socket.fd, &sock_exceptfds))
- n++;
- else
- FD_CLR(i, exceptfds);
- }
- break;
-#endif
- }
-#ifdef LIBC_VERBOSE
- if (FD_ISSET(i, readfds))
- nbread[i]++;
- if (FD_ISSET(i, writefds))
- nbwrite[i]++;
- if (FD_ISSET(i, exceptfds))
- nbexcept[i]++;
-#endif
- }
-#ifdef LIBC_VERBOSE
- if (NOW() > lastshown + 1000000000ull) {
- lastshown = NOW();
- printk("%lu MB free, ", num_free_pages() / ((1 << 20) / PAGE_SIZE));
- printk("%d(%d): ", nb, sock_n);
- for (i = 0; i < nfds; i++) {
- if (nbread[i] || nbwrite[i] || nbexcept[i])
- printk(" %d(%c):", i, file_types[files[i].type]);
- if (nbread[i])
- printk(" %dR", nbread[i]);
- if (nbwrite[i])
- printk(" %dW", nbwrite[i]);
- if (nbexcept[i])
- printk(" %dE", nbexcept[i]);
- }
- printk("\n");
- memset(nbread, 0, sizeof(nbread));
- memset(nbwrite, 0, sizeof(nbwrite));
- memset(nbexcept, 0, sizeof(nbexcept));
- nb = 0;
- }
-#endif
- return n;
-}
-
-/* The strategy is to
- * - announce that we will maybe sleep
- * - poll a bit ; if successful, return
- * - if timeout, return
- * - really sleep (except if somebody woke us in the meanwhile) */
-int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- struct timeval *timeout)
-{
- int n, ret;
- fd_set myread, mywrite, myexcept;
- struct thread *thread = get_current();
- s_time_t start = NOW(), stop;
-#ifdef CONFIG_NETFRONT
- DEFINE_WAIT(netfront_w);
-#endif
- DEFINE_WAIT(event_w);
-#ifdef CONFIG_BLKFRONT
- DEFINE_WAIT(blkfront_w);
-#endif
-#ifdef CONFIG_XENBUS
- DEFINE_WAIT(xenbus_watch_w);
-#endif
-#ifdef CONFIG_KBDFRONT
- DEFINE_WAIT(kbdfront_w);
-#endif
- DEFINE_WAIT(console_w);
-
- assert(thread == main_thread);
-
- DEBUG("select(%d, ", nfds);
- dump_set(nfds, readfds, writefds, exceptfds, timeout);
- DEBUG(");\n");
-
- if (timeout)
- stop = start + SECONDS(timeout->tv_sec) + timeout->tv_usec * 1000;
- else
- /* just make gcc happy */
- stop = start;
-
- /* Tell people we're going to sleep before looking at what they are
- * saying, hence letting them wake us if events happen between here and
- * schedule() */
-#ifdef CONFIG_NETFRONT
- add_waiter(netfront_w, netfront_queue);
-#endif
- add_waiter(event_w, event_queue);
-#ifdef CONFIG_BLKFRONT
- add_waiter(blkfront_w, blkfront_queue);
-#endif
-#ifdef CONFIG_XENBUS
- add_waiter(xenbus_watch_w, xenbus_watch_queue);
-#endif
-#ifdef CONFIG_KBDFRONT
- add_waiter(kbdfront_w, kbdfront_queue);
-#endif
- add_waiter(console_w, console_queue);
-
- if (readfds)
- myread = *readfds;
- else
- FD_ZERO(&myread);
- if (writefds)
- mywrite = *writefds;
- else
- FD_ZERO(&mywrite);
- if (exceptfds)
- myexcept = *exceptfds;
- else
- FD_ZERO(&myexcept);
-
- DEBUG("polling ");
- dump_set(nfds, &myread, &mywrite, &myexcept, timeout);
- DEBUG("\n");
- n = select_poll(nfds, &myread, &mywrite, &myexcept);
-
- if (n) {
- dump_set(nfds, readfds, writefds, exceptfds, timeout);
- if (readfds)
- *readfds = myread;
- if (writefds)
- *writefds = mywrite;
- if (exceptfds)
- *exceptfds = myexcept;
- DEBUG(" -> ");
- dump_set(nfds, readfds, writefds, exceptfds, timeout);
- DEBUG("\n");
- wake(thread);
- ret = n;
- goto out;
- }
- if (timeout && NOW() >= stop) {
- if (readfds)
- FD_ZERO(readfds);
- if (writefds)
- FD_ZERO(writefds);
- if (exceptfds)
- FD_ZERO(exceptfds);
- timeout->tv_sec = 0;
- timeout->tv_usec = 0;
- wake(thread);
- ret = 0;
- goto out;
- }
-
- if (timeout)
- thread->wakeup_time = stop;
- schedule();
-
- if (readfds)
- myread = *readfds;
- else
- FD_ZERO(&myread);
- if (writefds)
- mywrite = *writefds;
- else
- FD_ZERO(&mywrite);
- if (exceptfds)
- myexcept = *exceptfds;
- else
- FD_ZERO(&myexcept);
-
- n = select_poll(nfds, &myread, &mywrite, &myexcept);
-
- if (n) {
- if (readfds)
- *readfds = myread;
- if (writefds)
- *writefds = mywrite;
- if (exceptfds)
- *exceptfds = myexcept;
- ret = n;
- goto out;
- }
- errno = EINTR;
- ret = -1;
-
-out:
-#ifdef CONFIG_NETFRONT
- remove_waiter(netfront_w, netfront_queue);
-#endif
- remove_waiter(event_w, event_queue);
-#ifdef CONFIG_BLKFRONT
- remove_waiter(blkfront_w, blkfront_queue);
-#endif
-#ifdef CONFIG_XENBUS
- remove_waiter(xenbus_watch_w, xenbus_watch_queue);
-#endif
-#ifdef CONFIG_KBDFRONT
- remove_waiter(kbdfront_w, kbdfront_queue);
-#endif
- remove_waiter(console_w, console_queue);
- return ret;
-}
-
-/* Wrap around select */
-int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout)
-{
- int n, ret;
- int i, fd;
- struct timeval _timeo, *timeo = NULL;
- fd_set rfds, wfds, efds;
- int max_fd = -1;
-
- DEBUG("poll(");
- dump_pollfds(_pfd, _nfds, _timeout);
- DEBUG(")\n");
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&efds);
-
- n = 0;
-
- for (i = 0; i < _nfds; i++) {
- fd = _pfd[i].fd;
- _pfd[i].revents = 0;
-
- /* fd < 0, revents = 0, which is already set */
- if (fd < 0) continue;
-
- /* fd is invalid, revents = POLLNVAL, increment counter */
- if (fd >= NOFILE || files[fd].type == FTYPE_NONE) {
- n++;
- _pfd[i].revents |= POLLNVAL;
- continue;
- }
-
- /* normal case, map POLL* into readfds and writefds:
- * POLLIN -> readfds
- * POLLOUT -> writefds
- * POLL* -> none
- */
- if (_pfd[i].events & POLLIN)
- FD_SET(fd, &rfds);
- if (_pfd[i].events & POLLOUT)
- FD_SET(fd, &wfds);
- /* always set exceptfds */
- FD_SET(fd, &efds);
- if (fd > max_fd)
- max_fd = fd;
- }
-
- /* should never sleep when we already have events */
- if (n) {
- _timeo.tv_sec = 0;
- _timeo.tv_usec = 0;
- timeo = &_timeo;
- } else if (_timeout >= 0) {
- /* normal case, construct _timeout, might sleep */
- _timeo.tv_sec = _timeout / 1000;
- _timeo.tv_usec = (_timeout % 1000) * 1000;
- timeo = &_timeo;
- } else {
- /* _timeout < 0, block forever */
- timeo = NULL;
- }
-
-
- ret = select(max_fd+1, &rfds, &wfds, &efds, timeo);
- /* error in select, just return, errno is set by select() */
- if (ret < 0)
- return ret;
-
- for (i = 0; i < _nfds; i++) {
- fd = _pfd[i].fd;
-
- /* the revents has already been set for all error case */
- if (fd < 0 || fd >= NOFILE || files[fd].type == FTYPE_NONE)
- continue;
-
- if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds) || FD_ISSET(fd, &efds))
- n++;
- if (FD_ISSET(fd, &efds)) {
- /* anything bad happens we set POLLERR */
- _pfd[i].revents |= POLLERR;
- continue;
- }
- if (FD_ISSET(fd, &rfds))
- _pfd[i].revents |= POLLIN;
- if (FD_ISSET(fd, &wfds))
- _pfd[i].revents |= POLLOUT;
- }
-
- return n;
-}
-
-#ifdef HAVE_LWIP
-int socket(int domain, int type, int protocol)
-{
- int fd, res;
- fd = lwip_socket(domain, type, protocol);
- if (fd < 0)
- return -1;
- res = alloc_fd(FTYPE_SOCKET);
- printk("socket -> %d\n", res);
- files[res].socket.fd = fd;
- return res;
-}
-
-int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
-{
- int fd, res;
- if (files[s].type != FTYPE_SOCKET) {
- printk("accept(%d): Bad descriptor\n", s);
- errno = EBADF;
- return -1;
- }
- fd = lwip_accept(files[s].socket.fd, addr, addrlen);
- if (fd < 0)
- return -1;
- res = alloc_fd(FTYPE_SOCKET);
- files[res].socket.fd = fd;
- printk("accepted on %d -> %d\n", s, res);
- return res;
-}
-
-#define LWIP_STUB(ret, name, proto, args) \
-ret name proto \
-{ \
- if (files[s].type != FTYPE_SOCKET) { \
- printk(#name "(%d): Bad descriptor\n", s); \
- errno = EBADF; \
- return -1; \
- } \
- s = files[s].socket.fd; \
- return lwip_##name args; \
-}
-
-LWIP_STUB(int, bind, (int s, struct sockaddr *my_addr, socklen_t addrlen), (s, my_addr, addrlen))
-LWIP_STUB(int, getsockopt, (int s, int level, int optname, void *optval, socklen_t *optlen), (s, level, optname, optval, optlen))
-LWIP_STUB(int, setsockopt, (int s, int level, int optname, void *optval, socklen_t optlen), (s, level, optname, optval, optlen))
-LWIP_STUB(int, connect, (int s, struct sockaddr *serv_addr, socklen_t addrlen), (s, serv_addr, addrlen))
-LWIP_STUB(int, listen, (int s, int backlog), (s, backlog));
-LWIP_STUB(ssize_t, recv, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
-LWIP_STUB(ssize_t, recvfrom, (int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen), (s, buf, len, flags, from, fromlen))
-LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
-LWIP_STUB(ssize_t, sendto, (int s, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen), (s, buf, len, flags, to, tolen))
-LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen))
-#endif
-
-static char *syslog_ident;
-void openlog(const char *ident, int option, int facility)
-{
- free(syslog_ident);
- syslog_ident = strdup(ident);
-}
-
-void vsyslog(int priority, const char *format, va_list ap)
-{
- printk("%s: ", syslog_ident);
- print(0, format, ap);
-}
-
-void syslog(int priority, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- vsyslog(priority, format, ap);
- va_end(ap);
-}
-
-void closelog(void)
-{
- free(syslog_ident);
- syslog_ident = NULL;
-}
-
-void vwarn(const char *format, va_list ap)
-{
- int the_errno = errno;
- printk("stubdom: ");
- if (format) {
- print(0, format, ap);
- printk(", ");
- }
- printk("%s", strerror(the_errno));
-}
-
-void warn(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- vwarn(format, ap);
- va_end(ap);
-}
-
-void verr(int eval, const char *format, va_list ap)
-{
- vwarn(format, ap);
- exit(eval);
-}
-
-void err(int eval, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- verr(eval, format, ap);
- va_end(ap);
-}
-
-void vwarnx(const char *format, va_list ap)
-{
- printk("stubdom: ");
- if (format)
- print(0, format, ap);
-}
-
-void warnx(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- vwarnx(format, ap);
- va_end(ap);
-}
-
-void verrx(int eval, const char *format, va_list ap)
-{
- vwarnx(format, ap);
- exit(eval);
-}
-
-void errx(int eval, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- verrx(eval, format, ap);
- va_end(ap);
-}
-
-int nanosleep(const struct timespec *req, struct timespec *rem)
-{
- s_time_t start = NOW();
- s_time_t stop = start + SECONDS(req->tv_sec) + req->tv_nsec;
- s_time_t stopped;
- struct thread *thread = get_current();
-
- thread->wakeup_time = stop;
- clear_runnable(thread);
- schedule();
- stopped = NOW();
-
- if (rem)
- {
- s_time_t remaining = stop - stopped;
- if (remaining > 0)
- {
- rem->tv_nsec = remaining % 1000000000ULL;
- rem->tv_sec = remaining / 1000000000ULL;
- } else memset(rem, 0, sizeof(*rem));
- }
-
- return 0;
-}
-
-int usleep(useconds_t usec)
-{
- /* "usec shall be less than one million." */
- struct timespec req;
- req.tv_nsec = usec * 1000;
- req.tv_sec = 0;
-
- if (nanosleep(&req, NULL))
- return -1;
-
- return 0;
-}
-
-unsigned int sleep(unsigned int seconds)
-{
- struct timespec req, rem;
- req.tv_sec = seconds;
- req.tv_nsec = 0;
-
- if (nanosleep(&req, &rem))
- return -1;
-
- if (rem.tv_nsec > 0)
- rem.tv_sec++;
-
- return rem.tv_sec;
-}
-
-int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
- switch (clk_id) {
- case CLOCK_MONOTONIC:
- {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- tp->tv_sec = tv.tv_sec;
- tp->tv_nsec = tv.tv_usec * 1000;
-
- break;
- }
- case CLOCK_REALTIME:
- {
- uint64_t nsec = monotonic_clock();
-
- tp->tv_sec = nsec / 1000000000ULL;
- tp->tv_nsec = nsec % 1000000000ULL;
-
- break;
- }
- default:
- print_unsupported("clock_gettime(%d)", clk_id);
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-uid_t getuid(void)
-{
- return 0;
-}
-
-uid_t geteuid(void)
-{
- return 0;
-}
-
-gid_t getgid(void)
-{
- return 0;
-}
-
-gid_t getegid(void)
-{
- return 0;
-}
-
-int gethostname(char *name, size_t namelen)
-{
- strncpy(name, "mini-os", namelen);
- return 0;
-}
-
-size_t getpagesize(void)
-{
- return PAGE_SIZE;
-}
-
-void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
-{
- unsigned long n = (length + PAGE_SIZE - 1) / PAGE_SIZE;
-
- ASSERT(!start);
- ASSERT(prot == (PROT_READ|PROT_WRITE));
- ASSERT((fd == -1 && (flags == (MAP_SHARED|MAP_ANON) || flags == (MAP_PRIVATE|MAP_ANON)))
- || (fd != -1 && flags == MAP_SHARED));
-
- if (fd == -1)
- return map_zero(n, 1);
-#ifdef CONFIG_XC
- else if (files[fd].type == FTYPE_XC) {
- unsigned long zero = 0;
- return map_frames_ex(&zero, n, 0, 0, 1, DOMID_SELF, NULL, 0);
- }
-#endif
- else if (files[fd].type == FTYPE_MEM) {
- unsigned long first_mfn = offset >> PAGE_SHIFT;
- return map_frames_ex(&first_mfn, n, 0, 1, 1, DOMID_IO, NULL, _PAGE_PRESENT|_PAGE_RW);
- } else ASSERT(0);
-}
-
-int munmap(void *start, size_t length)
-{
- int total = length / PAGE_SIZE;
- int ret;
-
- ret = unmap_frames((unsigned long)start, (unsigned long)total);
- if (ret) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-void sparse(unsigned long data, size_t size)
-{
- unsigned long newdata;
- xen_pfn_t *mfns;
- int i, n;
-
- newdata = (data + PAGE_SIZE - 1) & PAGE_MASK;
- if (newdata - data > size)
- return;
- size -= newdata - data;
- data = newdata;
- n = size / PAGE_SIZE;
- size = n * PAGE_SIZE;
-
- mfns = malloc(n * sizeof(*mfns));
- for (i = 0; i < n; i++) {
-#ifdef LIBC_DEBUG
- int j;
- for (j=0; j<PAGE_SIZE; j++)
- if (((char*)data + i * PAGE_SIZE)[j]) {
- printk("%lx is not zero!\n", data + i * PAGE_SIZE + j);
- exit(1);
- }
-#endif
- mfns[i] = virtual_to_mfn(data + i * PAGE_SIZE);
- }
-
- printk("sparsing %ldMB at %lx\n", size >> 20, data);
-
- munmap((void *) data, size);
- free_physical_pages(mfns, n);
- do_map_zero(data, n);
-}
-
-int nice(int inc)
-{
- printk("nice() stub called with inc=%d\n", inc);
- return 0;
-}
-
-
-/* Not supported by FS yet. */
-unsupported_function_crash(link);
-unsupported_function(int, readlink, -1);
-unsupported_function_crash(umask);
-
-/* We could support that. */
-unsupported_function_log(int, chdir, -1);
-
-/* No dynamic library support. */
-unsupported_function_log(void *, dlopen, NULL);
-unsupported_function_log(void *, dlsym, NULL);
-unsupported_function_log(char *, dlerror, NULL);
-unsupported_function_log(int, dlclose, -1);
-
-/* We don't raise signals anyway. */
-unsupported_function(int, sigemptyset, -1);
-unsupported_function(int, sigfillset, -1);
-unsupported_function(int, sigaddset, -1);
-unsupported_function(int, sigdelset, -1);
-unsupported_function(int, sigismember, -1);
-unsupported_function(int, sigprocmask, -1);
-unsupported_function(int, sigaction, -1);
-unsupported_function(int, __sigsetjmp, 0);
-unsupported_function(int, sigaltstack, -1);
-unsupported_function_crash(kill);
-
-/* Unsupported */
-unsupported_function_crash(pipe);
-unsupported_function_crash(fork);
-unsupported_function_crash(execv);
-unsupported_function_crash(execve);
-unsupported_function_crash(waitpid);
-unsupported_function_crash(wait);
-unsupported_function_crash(lockf);
-unsupported_function_crash(sysconf);
-unsupported_function(int, tcsetattr, -1);
-unsupported_function(int, tcgetattr, 0);
-unsupported_function(int, grantpt, -1);
-unsupported_function(int, unlockpt, -1);
-unsupported_function(char *, ptsname, NULL);
-
-/* net/if.h */
-unsupported_function_log(unsigned int, if_nametoindex, -1);
-unsupported_function_log(char *, if_indextoname, (char *) NULL);
-unsupported_function_log(struct if_nameindex *, if_nameindex, (struct if_nameindex *) NULL);
-unsupported_function_crash(if_freenameindex);
-
-/* Linuxish abi for the Caml runtime, don't support
- Log, and return an error code if possible. If it is not possible
- to inform the application of an error, then crash instead!
-*/
-unsupported_function_log(struct dirent *, readdir64, NULL);
-unsupported_function_log(int, getrusage, -1);
-unsupported_function_log(int, getrlimit, -1);
-unsupported_function_log(int, getrlimit64, -1);
-unsupported_function_log(int, __xstat64, -1);
-unsupported_function_log(long, __strtol_internal, LONG_MIN);
-unsupported_function_log(double, __strtod_internal, HUGE_VAL);
-unsupported_function_log(int, utime, -1);
-unsupported_function_log(int, truncate64, -1);
-unsupported_function_log(int, tcflow, -1);
-unsupported_function_log(int, tcflush, -1);
-unsupported_function_log(int, tcdrain, -1);
-unsupported_function_log(int, tcsendbreak, -1);
-unsupported_function_log(int, cfsetospeed, -1);
-unsupported_function_log(int, cfsetispeed, -1);
-unsupported_function_crash(cfgetospeed);
-unsupported_function_crash(cfgetispeed);
-unsupported_function_log(int, symlink, -1);
-unsupported_function_log(const char*, inet_ntop, NULL);
-unsupported_function_crash(__fxstat64);
-unsupported_function_crash(__lxstat64);
-unsupported_function_log(int, socketpair, -1);
-unsupported_function_crash(sigsuspend);
-unsupported_function_log(int, sigpending, -1);
-unsupported_function_log(int, shutdown, -1);
-unsupported_function_log(int, setuid, -1);
-unsupported_function_log(int, setgid, -1);
-unsupported_function_crash(rewinddir);
-unsupported_function_log(int, getpriority, -1);
-unsupported_function_log(int, setpriority, -1);
-unsupported_function_log(int, mkfifo, -1);
-unsupported_function_log(int, getitimer, -1);
-unsupported_function_log(int, setitimer, -1);
-unsupported_function_log(void *, getservbyport, NULL);
-unsupported_function_log(void *, getservbyname, NULL);
-unsupported_function_log(void *, getpwuid, NULL);
-unsupported_function_log(void *, getpwnam, NULL);
-unsupported_function_log(void *, getprotobynumber, NULL);
-unsupported_function_log(void *, getprotobyname, NULL);
-unsupported_function_log(int, getpeername, -1);
-unsupported_function_log(int, getnameinfo, -1);
-unsupported_function_log(char *, getlogin, NULL);
-unsupported_function_crash(__h_errno_location);
-unsupported_function_log(int, gethostbyname_r, -1);
-unsupported_function_log(int, gethostbyaddr_r, -1);
-unsupported_function_log(int, getgroups, -1);
-unsupported_function_log(void *, getgrgid, NULL);
-unsupported_function_log(void *, getgrnam, NULL);
-unsupported_function_log(int, getaddrinfo, -1);
-unsupported_function_log(int, freeaddrinfo, -1);
-unsupported_function_log(int, ftruncate64, -1);
-unsupported_function_log(int, fchown, -1);
-unsupported_function_log(int, fchmod, -1);
-unsupported_function_crash(execvp);
-unsupported_function_log(int, dup, -1)
-unsupported_function_log(int, chroot, -1)
-unsupported_function_log(int, chown, -1);
-unsupported_function_log(int, chmod, -1);
-unsupported_function_crash(alarm);
-unsupported_function_log(int, inet_pton, -1);
-unsupported_function_log(int, access, -1);
-#endif
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: xmaloc.c
- * Author: Grzegorz Milos (gm281@cam.ac.uk)
- * Samuel Thibault (samuel.thibault@eu.citrix.com)
- * Changes:
- *
- * Date: Aug 2005
- * Jan 2008
- *
- * Environment: Xen Minimal OS
- * Description: simple memory allocator
- *
- ****************************************************************************
- * Simple allocator for Mini-os. If larger than a page, simply use the
- * page-order allocator.
- *
- * Copy of the allocator for Xen by Rusty Russell:
- * Copyright (C) 2005 Rusty Russell IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <mini-os/os.h>
-#include <mini-os/mm.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/list.h>
-#include <mini-os/xmalloc.h>
-
-#ifndef HAVE_LIBC
-/* static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED; */
-
-struct xmalloc_hdr
-{
- /* Total including this hdr, unused padding and second hdr. */
- size_t size;
- MINIOS_TAILQ_ENTRY(struct xmalloc_hdr) freelist;
-} __cacheline_aligned;
-
-static MINIOS_TAILQ_HEAD(,struct xmalloc_hdr) freelist =
- MINIOS_TAILQ_HEAD_INITIALIZER(freelist);
-
-/* Unused padding data between the two hdrs. */
-
-struct xmalloc_pad
-{
- /* Size including both hdrs. */
- size_t hdr_size;
-};
-
-/* Return size, increased to alignment with align. */
-static inline size_t align_up(size_t size, size_t align)
-{
- return (size + align - 1) & ~(align - 1);
-}
-
-static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block)
-{
- struct xmalloc_hdr *extra;
- size_t leftover;
- size = align_up(size, __alignof__(struct xmalloc_hdr));
- size = align_up(size, __alignof__(struct xmalloc_pad));
- leftover = block - size;
-
- /* If enough is left to make a block, put it on free list. */
- if ( leftover >= (2 * (sizeof(struct xmalloc_hdr) + sizeof(struct xmalloc_pad))) )
- {
- extra = (struct xmalloc_hdr *)((unsigned long)hdr + size);
- extra->size = leftover;
- /* spin_lock_irqsave(&freelist_lock, flags); */
- MINIOS_TAILQ_INSERT_HEAD(&freelist, extra, freelist);
- /* spin_unlock_irqrestore(&freelist_lock, flags); */
- }
- else
- {
- size = block;
- }
-
- hdr->size = size;
-}
-
-static struct xmalloc_hdr *xmalloc_new_page(size_t size)
-{
- struct xmalloc_hdr *hdr;
- /* unsigned long flags; */
-
- hdr = (struct xmalloc_hdr *)alloc_page();
- if ( hdr == NULL )
- return NULL;
-
- maybe_split(hdr, size, PAGE_SIZE);
-
- return hdr;
-}
-
-/* Big object? Just use the page allocator. */
-static void *xmalloc_whole_pages(size_t size, size_t align)
-{
- struct xmalloc_hdr *hdr;
- struct xmalloc_pad *pad;
- unsigned int pageorder;
- void *ret;
- /* Room for headers */
- size_t hdr_size = sizeof(struct xmalloc_hdr) + sizeof(struct xmalloc_pad);
- /* Align for actual beginning of data */
- hdr_size = align_up(hdr_size, align);
-
- pageorder = get_order(hdr_size + size);
-
- hdr = (struct xmalloc_hdr *)alloc_pages(pageorder);
- if ( hdr == NULL )
- return NULL;
-
- hdr->size = (1UL << (pageorder + PAGE_SHIFT));
-
- ret = (char*)hdr + hdr_size;
- pad = (struct xmalloc_pad *) ret - 1;
- pad->hdr_size = hdr_size;
- return ret;
-}
-
-void *_xmalloc(size_t size, size_t align)
-{
- struct xmalloc_hdr *i, *tmp, *hdr = NULL;
- uintptr_t data_begin;
- size_t hdr_size;
- /* unsigned long flags; */
-
- hdr_size = sizeof(struct xmalloc_hdr) + sizeof(struct xmalloc_pad);
- /* Align on headers requirements. */
- align = align_up(align, __alignof__(struct xmalloc_hdr));
- align = align_up(align, __alignof__(struct xmalloc_pad));
-
- /* For big allocs, give them whole pages. */
- if ( size + align_up(hdr_size, align) >= PAGE_SIZE )
- return xmalloc_whole_pages(size, align);
-
- /* Search free list. */
- /* spin_lock_irqsave(&freelist_lock, flags); */
- MINIOS_TAILQ_FOREACH_SAFE(i, &freelist, freelist, tmp)
- {
- data_begin = align_up((uintptr_t)i + hdr_size, align);
-
- if ( data_begin + size > (uintptr_t)i + i->size )
- continue;
-
- MINIOS_TAILQ_REMOVE(&freelist, i, freelist);
- /* spin_unlock_irqrestore(&freelist_lock, flags); */
-
- uintptr_t size_before = (data_begin - hdr_size) - (uintptr_t)i;
-
- if (size_before >= 2 * hdr_size) {
- /* Worth splitting the beginning */
- struct xmalloc_hdr *new_i = (void*)(data_begin - hdr_size);
- new_i->size = i->size - size_before;
- i->size = size_before;
- /* spin_lock_irqsave(&freelist_lock, flags); */
- MINIOS_TAILQ_INSERT_HEAD(&freelist, i, freelist);
- /* spin_unlock_irqrestore(&freelist_lock, flags); */
- i = new_i;
- }
- maybe_split(i, (data_begin + size) - (uintptr_t)i, i->size);
- hdr = i;
- break;
- }
-
- if (!hdr) {
- /* spin_unlock_irqrestore(&freelist_lock, flags); */
-
- /* Alloc a new page and return from that. */
- hdr = xmalloc_new_page(align_up(hdr_size, align) + size);
- if ( hdr == NULL )
- return NULL;
- data_begin = (uintptr_t)hdr + align_up(hdr_size, align);
- }
-
- struct xmalloc_pad *pad = (struct xmalloc_pad *) data_begin - 1;
- pad->hdr_size = data_begin - (uintptr_t)hdr;
- BUG_ON(data_begin % align);
- return (void*)data_begin;
-}
-
-void xfree(const void *p)
-{
- /* unsigned long flags; */
- struct xmalloc_hdr *i, *tmp, *hdr;
- struct xmalloc_pad *pad;
-
- if ( p == NULL )
- return;
-
- pad = (struct xmalloc_pad *)p - 1;
- hdr = (struct xmalloc_hdr *)((char *)p - pad->hdr_size);
-
- /* Big allocs free directly. */
- if ( hdr->size >= PAGE_SIZE )
- {
- free_pages(hdr, get_order(hdr->size));
- return;
- }
-
- /* We know hdr will be on same page. */
- if(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK))
- {
- printk("Header should be on the same page\n");
- *(int*)0=0;
- }
-
- /* Merge with other free block, or put in list. */
- /* spin_lock_irqsave(&freelist_lock, flags); */
- MINIOS_TAILQ_FOREACH_SAFE(i, &freelist, freelist, tmp)
- {
- unsigned long _i = (unsigned long)i;
- unsigned long _hdr = (unsigned long)hdr;
-
- /* Do not merge across page boundaries. */
- if ( ((_i ^ _hdr) & PAGE_MASK) != 0 )
- continue;
-
- /* We follow this block? Swallow it. */
- if ( (_i + i->size) == _hdr )
- {
- MINIOS_TAILQ_REMOVE(&freelist, i, freelist);
- i->size += hdr->size;
- hdr = i;
- }
-
- /* We precede this block? Swallow it. */
- if ( (_hdr + hdr->size) == _i )
- {
- MINIOS_TAILQ_REMOVE(&freelist, i, freelist);
- hdr->size += i->size;
- }
- }
-
- /* Did we merge an entire page? */
- if ( hdr->size == PAGE_SIZE )
- {
- if((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0)
- {
- printk("Bug\n");
- *(int*)0=0;
- }
- free_page(hdr);
- }
- else
- {
- MINIOS_TAILQ_INSERT_HEAD(&freelist, hdr, freelist);
- }
-
- /* spin_unlock_irqrestore(&freelist_lock, flags); */
-}
-
-void *malloc(size_t size)
-{
- return _xmalloc(size, DEFAULT_ALIGN);
-}
-
-void *realloc(void *ptr, size_t size)
-{
- void *new;
- struct xmalloc_hdr *hdr;
- struct xmalloc_pad *pad;
- size_t old_data_size;
-
- if (ptr == NULL)
- return _xmalloc(size, DEFAULT_ALIGN);
-
- pad = (struct xmalloc_pad *)ptr - 1;
- hdr = (struct xmalloc_hdr *)((char*)ptr - pad->hdr_size);
-
- old_data_size = hdr->size - pad->hdr_size;
- if ( old_data_size >= size )
- {
- maybe_split(hdr, pad->hdr_size + size, hdr->size);
- return ptr;
- }
-
- new = _xmalloc(size, DEFAULT_ALIGN);
- if (new == NULL)
- return NULL;
-
- memcpy(new, ptr, old_data_size);
- xfree(ptr);
-
- return new;
-}
-
-void free(void *ptr)
-{
- xfree(ptr);
-}
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/*
- * libxs-compatible layer
- *
- * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 2007-2008
- *
- * Mere wrapper around xenbus_*
- */
-
-#ifdef HAVE_LIBC
-#include <os.h>
-#include <lib.h>
-#include <xenstore.h>
-#include <xenbus.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static inline int _xs_fileno(struct xs_handle *h) {
- return (intptr_t) h;
-}
-
-struct xs_handle *xs_daemon_open()
-{
- int fd = alloc_fd(FTYPE_XENBUS);
- files[fd].xenbus.events = NULL;
- printk("xs_daemon_open -> %d, %p\n", fd, &files[fd].xenbus.events);
- return (void*)(intptr_t) fd;
-}
-
-void xs_daemon_close(struct xs_handle *h)
-{
- int fd = _xs_fileno(h);
- struct xenbus_event *event, *next;
- for (event = files[fd].xenbus.events; event; event = next)
- {
- next = event->next;
- free(event);
- }
- files[fd].type = FTYPE_NONE;
-}
-
-int xs_fileno(struct xs_handle *h)
-{
- return _xs_fileno(h);
-}
-
-void *xs_read(struct xs_handle *h, xs_transaction_t t,
- const char *path, unsigned int *len)
-{
- char *value;
- char *msg;
-
- msg = xenbus_read(t, path, &value);
- if (msg) {
- printk("xs_read(%s): %s\n", path, msg);
- free(msg);
- return NULL;
- }
-
- if (len)
- *len = strlen(value);
- return value;
-}
-
-bool xs_write(struct xs_handle *h, xs_transaction_t t,
- const char *path, const void *data, unsigned int len)
-{
- char value[len + 1];
- char *msg;
-
- memcpy(value, data, len);
- value[len] = 0;
-
- msg = xenbus_write(t, path, value);
- if (msg) {
- printk("xs_write(%s): %s\n", path, msg);
- free(msg);
- return false;
- }
- return true;
-}
-
-static bool xs_bool(char *reply)
-{
- if (!reply)
- return true;
- free(reply);
- return false;
-}
-
-bool xs_rm(struct xs_handle *h, xs_transaction_t t, const char *path)
-{
- return xs_bool(xenbus_rm(t, path));
-}
-
-static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
- enum xsd_sockmsg_type type,
- struct write_req *iovec,
- unsigned int num_vecs,
- unsigned int *len)
-{
- struct xsd_sockmsg *msg;
- void *ret;
-
- msg = xenbus_msg_reply(type, t, iovec, num_vecs);
- ret = malloc(msg->len);
- memcpy(ret, (char*) msg + sizeof(*msg), msg->len);
- if (len)
- *len = msg->len - 1;
- free(msg);
- return ret;
-}
-
-static void *xs_single(struct xs_handle *h, xs_transaction_t t,
- enum xsd_sockmsg_type type,
- const char *string,
- unsigned int *len)
-{
- struct write_req iovec;
-
- iovec.data = (void *)string;
- iovec.len = strlen(string) + 1;
-
- return xs_talkv(h, t, type, &iovec, 1, len);
-}
-
-char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
-{
- char domid_str[MAX_STRLEN(domid)];
-
- sprintf(domid_str, "%u", domid);
-
- return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
-}
-
-char **xs_directory(struct xs_handle *h, xs_transaction_t t,
- const char *path, unsigned int *num)
-{
- char *msg;
- char **entries, **res;
- char *entry;
- int i, n;
- int size;
-
- msg = xenbus_ls(t, path, &res);
- if (msg) {
- printk("xs_directory(%s): %s\n", path, msg);
- free(msg);
- return NULL;
- }
-
- size = 0;
- for (n = 0; res[n]; n++)
- size += strlen(res[n]) + 1;
-
- entries = malloc(n * sizeof(char *) + size);
- entry = (char *) (&entries[n]);
-
- for (i = 0; i < n; i++) {
- int l = strlen(res[i]) + 1;
- memcpy(entry, res[i], l);
- free(res[i]);
- entries[i] = entry;
- entry += l;
- }
-
- *num = n;
- free(res);
- return entries;
-}
-
-bool xs_watch(struct xs_handle *h, const char *path, const char *token)
-{
- int fd = _xs_fileno(h);
- printk("xs_watch(%s, %s)\n", path, token);
- return xs_bool(xenbus_watch_path_token(XBT_NULL, path, token, &files[fd].xenbus.events));
-}
-
-char **xs_read_watch(struct xs_handle *h, unsigned int *num)
-{
- int fd = _xs_fileno(h);
- struct xenbus_event *event;
- event = files[fd].xenbus.events;
- files[fd].xenbus.events = event->next;
- printk("xs_read_watch() -> %s %s\n", event->path, event->token);
- *num = 2;
- return (char **) &event->path;
-}
-
-bool xs_unwatch(struct xs_handle *h, const char *path, const char *token)
-{
- printk("xs_unwatch(%s, %s)\n", path, token);
- return xs_bool(xenbus_unwatch_path_token(XBT_NULL, path, token));
-}
-#endif
+++ /dev/null
-/*
- * locks for newlib
- *
- * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, July 20008
- */
-
-#ifdef HAVE_LIBC
-
-#include <sys/lock.h>
-#include <sched.h>
-#include <wait.h>
-#include <mini-os/lib.h>
-
-int ___lock_init(_LOCK_T *lock)
-{
- lock->busy = 0;
- init_waitqueue_head(&lock->wait);
- return 0;
-}
-
-int ___lock_acquire(_LOCK_T *lock)
-{
- unsigned long flags;
- while(1) {
- wait_event(lock->wait, !lock->busy);
- local_irq_save(flags);
- if (!lock->busy)
- break;
- local_irq_restore(flags);
- }
- lock->busy = 1;
- local_irq_restore(flags);
- return 0;
-}
-
-int ___lock_try_acquire(_LOCK_T *lock)
-{
- unsigned long flags;
- int ret = -1;
- local_irq_save(flags);
- if (!lock->busy) {
- lock->busy = 1;
- ret = 0;
- }
- local_irq_restore(flags);
- return ret;
-}
-
-int ___lock_release(_LOCK_T *lock)
-{
- unsigned long flags;
- local_irq_save(flags);
- lock->busy = 0;
- wake_up(&lock->wait);
- local_irq_restore(flags);
- return 0;
-}
-
-
-int ___lock_init_recursive(_LOCK_RECURSIVE_T *lock)
-{
- lock->owner = NULL;
- init_waitqueue_head(&lock->wait);
- return 0;
-}
-
-int ___lock_acquire_recursive(_LOCK_RECURSIVE_T *lock)
-{
- unsigned long flags;
- if (lock->owner != get_current()) {
- while (1) {
- wait_event(lock->wait, lock->owner == NULL);
- local_irq_save(flags);
- if (lock->owner == NULL)
- break;
- local_irq_restore(flags);
- }
- lock->owner = get_current();
- local_irq_restore(flags);
- }
- lock->count++;
- return 0;
-}
-
-int ___lock_try_acquire_recursive(_LOCK_RECURSIVE_T *lock)
-{
- unsigned long flags;
- int ret = -1;
- local_irq_save(flags);
- if (!lock->owner) {
- ret = 0;
- lock->owner = get_current();
- lock->count++;
- }
- local_irq_restore(flags);
- return ret;
-}
-
-int ___lock_release_recursive(_LOCK_RECURSIVE_T *lock)
-{
- unsigned long flags;
- BUG_ON(lock->owner != get_current());
- if (--lock->count)
- return 0;
- local_irq_save(flags);
- lock->owner = NULL;
- wake_up(&lock->wait);
- local_irq_restore(flags);
- return 0;
-}
-
-#endif
+++ /dev/null
-/*
- * lwip-arch.c
- *
- * Arch-specific semaphores and mailboxes for lwIP running on mini-os
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- */
-
-#include <os.h>
-#include <time.h>
-#include <console.h>
-#include <xmalloc.h>
-#include <lwip/sys.h>
-#include <stdarg.h>
-
-/* Is called to initialize the sys_arch layer */
-void sys_init(void)
-{
-}
-
-/* Creates and returns a new semaphore. The "count" argument specifies
- * the initial state of the semaphore. */
-sys_sem_t sys_sem_new(uint8_t count)
-{
- struct semaphore *sem = xmalloc(struct semaphore);
- sem->count = count;
- init_waitqueue_head(&sem->wait);
- return sem;
-}
-
-/* Deallocates a semaphore. */
-void sys_sem_free(sys_sem_t sem)
-{
- xfree(sem);
-}
-
-/* Signals a semaphore. */
-void sys_sem_signal(sys_sem_t sem)
-{
- up(sem);
-}
-
-/* Blocks the thread while waiting for the semaphore to be
- * signaled. If the "timeout" argument is non-zero, the thread should
- * only be blocked for the specified time (measured in
- * milliseconds).
- *
- * If the timeout argument is non-zero, the return value is the number of
- * milliseconds spent waiting for the semaphore to be signaled. If the
- * semaphore wasn't signaled within the specified time, the return value is
- * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
- * (i.e., it was already signaled), the function may return zero. */
-uint32_t sys_arch_sem_wait(sys_sem_t sem, uint32_t timeout)
-{
- /* Slightly more complicated than the normal minios semaphore:
- * need to wake on timeout *or* signal */
- sys_prot_t prot;
- int64_t then = NOW();
- int64_t deadline;
-
- if (timeout == 0)
- deadline = 0;
- else
- deadline = then + MILLISECS(timeout);
-
- while(1) {
- wait_event_deadline(sem->wait, (sem->count > 0), deadline);
-
- prot = sys_arch_protect();
- /* Atomically check that we can proceed */
- if (sem->count > 0 || (deadline && NOW() >= deadline))
- break;
- sys_arch_unprotect(prot);
- }
-
- if (sem->count > 0) {
- sem->count--;
- sys_arch_unprotect(prot);
- return NSEC_TO_MSEC(NOW() - then);
- }
-
- sys_arch_unprotect(prot);
- return SYS_ARCH_TIMEOUT;
-}
-
-/* Creates an empty mailbox. */
-sys_mbox_t sys_mbox_new(int size)
-{
- struct mbox *mbox = xmalloc(struct mbox);
- if (!size)
- size = 32;
- else if (size == 1)
- size = 2;
- mbox->count = size;
- mbox->messages = xmalloc_array(void*, size);
- init_SEMAPHORE(&mbox->read_sem, 0);
- mbox->reader = 0;
- init_SEMAPHORE(&mbox->write_sem, size);
- mbox->writer = 0;
- return mbox;
-}
-
-/* Deallocates a mailbox. If there are messages still present in the
- * mailbox when the mailbox is deallocated, it is an indication of a
- * programming error in lwIP and the developer should be notified. */
-void sys_mbox_free(sys_mbox_t mbox)
-{
- ASSERT(mbox->reader == mbox->writer);
- xfree(mbox->messages);
- xfree(mbox);
-}
-
-/* Posts the "msg" to the mailbox, internal version that actually does the
- * post. */
-static void do_mbox_post(sys_mbox_t mbox, void *msg)
-{
- /* The caller got a semaphore token, so we are now allowed to increment
- * writer, but we still need to prevent concurrency between writers
- * (interrupt handler vs main) */
- sys_prot_t prot = sys_arch_protect();
- mbox->messages[mbox->writer] = msg;
- mbox->writer = (mbox->writer + 1) % mbox->count;
- ASSERT(mbox->reader != mbox->writer);
- sys_arch_unprotect(prot);
- up(&mbox->read_sem);
-}
-
-/* Posts the "msg" to the mailbox. */
-void sys_mbox_post(sys_mbox_t mbox, void *msg)
-{
- if (mbox == SYS_MBOX_NULL)
- return;
- down(&mbox->write_sem);
- do_mbox_post(mbox, msg);
-}
-
-/* Try to post the "msg" to the mailbox. */
-err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
-{
- if (mbox == SYS_MBOX_NULL)
- return ERR_BUF;
- if (!trydown(&mbox->write_sem))
- return ERR_MEM;
- do_mbox_post(mbox, msg);
- return ERR_OK;
-}
-
-/*
- * Fetch a message from a mailbox. Internal version that actually does the
- * fetch.
- */
-static void do_mbox_fetch(sys_mbox_t mbox, void **msg)
-{
- sys_prot_t prot;
- /* The caller got a semaphore token, so we are now allowed to increment
- * reader, but we may still need to prevent concurrency between readers.
- * FIXME: can there be concurrent readers? */
- prot = sys_arch_protect();
- ASSERT(mbox->reader != mbox->writer);
- if (msg != NULL)
- *msg = mbox->messages[mbox->reader];
- mbox->reader = (mbox->reader + 1) % mbox->count;
- sys_arch_unprotect(prot);
- up(&mbox->write_sem);
-}
-
-/* Blocks the thread until a message arrives in the mailbox, but does
- * not block the thread longer than "timeout" milliseconds (similar to
- * the sys_arch_sem_wait() function). The "msg" argument is a result
- * parameter that is set by the function (i.e., by doing "*msg =
- * ptr"). The "msg" parameter maybe NULL to indicate that the message
- * should be dropped.
- *
- * The return values are the same as for the sys_arch_sem_wait() function:
- * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
- * timeout. */
-uint32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, uint32_t timeout)
-{
- uint32_t rv;
- if (mbox == SYS_MBOX_NULL)
- return SYS_ARCH_TIMEOUT;
-
- rv = sys_arch_sem_wait(&mbox->read_sem, timeout);
- if ( rv == SYS_ARCH_TIMEOUT )
- return rv;
-
- do_mbox_fetch(mbox, msg);
- return 0;
-}
-
-/* This is similar to sys_arch_mbox_fetch, however if a message is not
- * present in the mailbox, it immediately returns with the code
- * SYS_MBOX_EMPTY. On success 0 is returned.
- *
- * To allow for efficient implementations, this can be defined as a
- * function-like macro in sys_arch.h instead of a normal function. For
- * example, a naive implementation could be:
- * #define sys_arch_mbox_tryfetch(mbox,msg) \
- * sys_arch_mbox_fetch(mbox,msg,1)
- * although this would introduce unnecessary delays. */
-
-uint32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) {
- if (mbox == SYS_MBOX_NULL)
- return SYS_ARCH_TIMEOUT;
-
- if (!trydown(&mbox->read_sem))
- return SYS_MBOX_EMPTY;
-
- do_mbox_fetch(mbox, msg);
- return 0;
-}
-
-
-/* Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
- * each thread has a list of timeouts which is repressented as a linked
- * list of sys_timeout structures. The sys_timeouts structure holds a
- * pointer to a linked list of timeouts. This function is called by
- * the lwIP timeout scheduler and must not return a NULL value.
- *
- * In a single threadd sys_arch implementation, this function will
- * simply return a pointer to a global sys_timeouts variable stored in
- * the sys_arch module. */
-struct sys_timeouts *sys_arch_timeouts(void)
-{
- static struct sys_timeouts timeout;
- return &timeout;
-}
-
-
-/* Starts a new thread with priority "prio" that will begin its execution in the
- * function "thread()". The "arg" argument will be passed as an argument to the
- * thread() function. The id of the new thread is returned. Both the id and
- * the priority are system dependent. */
-static struct thread *lwip_thread;
-sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
-{
- struct thread *t;
- if (stacksize > STACK_SIZE) {
- printk("Can't start lwIP thread: stack size %d is too large for our %d\n", stacksize, STACK_SIZE);
- do_exit();
- }
- lwip_thread = t = create_thread(name, thread, arg);
- return t;
-}
-
-/* This optional function does a "fast" critical region protection and returns
- * the previous protection level. This function is only called during very short
- * critical regions. An embedded system which supports ISR-based drivers might
- * want to implement this function by disabling interrupts. Task-based systems
- * might want to implement this by using a mutex or disabling tasking. This
- * function should support recursive calls from the same task or interrupt. In
- * other words, sys_arch_protect() could be called while already protected. In
- * that case the return value indicates that it is already protected.
- *
- * sys_arch_protect() is only required if your port is supporting an operating
- * system. */
-sys_prot_t sys_arch_protect(void)
-{
- unsigned long flags;
- local_irq_save(flags);
- return flags;
-}
-
-/* This optional function does a "fast" set of critical region protection to the
- * value specified by pval. See the documentation for sys_arch_protect() for
- * more information. This function is only required if your port is supporting
- * an operating system. */
-void sys_arch_unprotect(sys_prot_t pval)
-{
- local_irq_restore(pval);
-}
-
-/* non-fatal, print a message. */
-void lwip_printk(char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- printk("lwIP: ");
- print(0, fmt, args);
- va_end(args);
-}
-
-/* fatal, print message and abandon execution. */
-void lwip_die(char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- printk("lwIP assertion failed: ");
- print(0, fmt, args);
- va_end(args);
- printk("\n");
- BUG();
-}
+++ /dev/null
-/*
- * lwip-net.c
- *
- * interface between lwIP's ethernet and Mini-os's netfront.
- * For now, support only one network interface, as mini-os does.
- *
- * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
- * based on lwIP's ethernetif.c skeleton file, copyrights as below.
- */
-
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include <os.h>
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-
-#include <lwip/stats.h>
-#include <lwip/sys.h>
-#include <lwip/mem.h>
-#include <lwip/memp.h>
-#include <lwip/pbuf.h>
-#include <netif/etharp.h>
-#include <lwip/tcpip.h>
-#include <lwip/tcp.h>
-#include <lwip/netif.h>
-#include <lwip/dhcp.h>
-
-#include "netif/etharp.h"
-
-#include <netfront.h>
-
-/* Define those to better describe your network interface. */
-#define IFNAME0 'e'
-#define IFNAME1 'n'
-
-#define IF_IPADDR 0x00000000
-#define IF_NETMASK 0x00000000
-
-/* Only have one network interface at a time. */
-static struct netif *the_interface = NULL;
-
-static unsigned char rawmac[6];
-static struct netfront_dev *dev;
-
-/* Forward declarations. */
-static err_t netfront_output(struct netif *netif, struct pbuf *p,
- struct ip_addr *ipaddr);
-
-/*
- * low_level_output():
- *
- * Should do the actual transmission of the packet. The packet is
- * contained in the pbuf that is passed to the function. This pbuf
- * might be chained.
- *
- */
-
-static err_t
-low_level_output(struct netif *netif, struct pbuf *p)
-{
- if (!dev)
- return ERR_OK;
-
-#ifdef ETH_PAD_SIZE
- pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
-#endif
-
- /* Send the data from the pbuf to the interface, one pbuf at a
- time. The size of the data in each pbuf is kept in the ->len
- variable. */
- if (!p->next) {
- /* Only one fragment, can send it directly */
- netfront_xmit(dev, p->payload, p->len);
- } else {
- unsigned char data[p->tot_len], *cur;
- struct pbuf *q;
-
- for(q = p, cur = data; q != NULL; cur += q->len, q = q->next)
- memcpy(cur, q->payload, q->len);
- netfront_xmit(dev, data, p->tot_len);
- }
-
-#if ETH_PAD_SIZE
- pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
-#endif
-
- LINK_STATS_INC(link.xmit);
-
- return ERR_OK;
-}
-
-
-
-/*
- * netfront_output():
- *
- * This function is called by the TCP/IP stack when an IP packet
- * should be sent. It calls the function called low_level_output() to
- * do the actual transmission of the packet.
- *
- */
-
-static err_t
-netfront_output(struct netif *netif, struct pbuf *p,
- struct ip_addr *ipaddr)
-{
-
- /* resolve hardware address, then send (or queue) packet */
- return etharp_output(netif, p, ipaddr);
-
-}
-
-/*
- * netfront_input():
- *
- * This function should be called when a packet is ready to be read
- * from the interface.
- *
- */
-
-static void
-netfront_input(struct netif *netif, unsigned char* data, int len)
-{
- struct eth_hdr *ethhdr;
- struct pbuf *p, *q;
-
-#if ETH_PAD_SIZE
- len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
-#endif
-
- /* move received packet into a new pbuf */
- p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
- if (p == NULL) {
- LINK_STATS_INC(link.memerr);
- LINK_STATS_INC(link.drop);
- return;
- }
-
-#if ETH_PAD_SIZE
- pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
-#endif
-
- /* We iterate over the pbuf chain until we have read the entire
- * packet into the pbuf. */
- for(q = p; q != NULL && len > 0; q = q->next) {
- /* Read enough bytes to fill this pbuf in the chain. The
- * available data in the pbuf is given by the q->len
- * variable. */
- memcpy(q->payload, data, len < q->len ? len : q->len);
- data += q->len;
- len -= q->len;
- }
-
-#if ETH_PAD_SIZE
- pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
-#endif
-
- LINK_STATS_INC(link.recv);
-
- /* points to packet payload, which starts with an Ethernet header */
- ethhdr = p->payload;
-
- switch (htons(ethhdr->type)) {
- /* IP packet? */
- case ETHTYPE_IP:
-#if 0
-/* CSi disabled ARP table update on ingress IP packets.
- This seems to work but needs thorough testing. */
- /* update ARP table */
- etharp_ip_input(netif, p);
-#endif
- /* skip Ethernet header */
- pbuf_header(p, -(int16_t)sizeof(struct eth_hdr));
- /* pass to network layer */
- if (tcpip_input(p, netif) == ERR_MEM)
- /* Could not store it, drop */
- pbuf_free(p);
- break;
-
- case ETHTYPE_ARP:
- /* pass p to ARP module */
- etharp_arp_input(netif, (struct eth_addr *) netif->hwaddr, p);
- break;
-
- default:
- pbuf_free(p);
- p = NULL;
- break;
- }
-}
-
-
-/*
- * netif_rx(): overrides the default netif_rx behaviour in the netfront driver.
- *
- * Pull received packets into a pbuf queue for the low_level_input()
- * function to pass up to lwIP.
- */
-
-void netif_rx(unsigned char* data, int len)
-{
- if (the_interface != NULL) {
- netfront_input(the_interface, data, len);
- wake_up(&netfront_queue);
- }
- /* By returning, we ack the packet and relinquish the RX ring slot */
-}
-
-/*
- * Set the IP, mask and gateway of the IF
- */
-void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw)
-{
- netif_set_ipaddr(the_interface, ipaddr);
- netif_set_netmask(the_interface, netmask);
- netif_set_gw(the_interface, gw);
-}
-
-
-static void
-arp_timer(void *arg)
-{
- etharp_tmr();
- sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
-}
-
-/*
- * netif_netfront_init():
- *
- * Should be called at the beginning of the program to set up the
- * network interface. It calls the function low_level_init() to do the
- * actual setup of the hardware.
- *
- */
-
-err_t
-netif_netfront_init(struct netif *netif)
-{
- unsigned char *mac = netif->state;
-
-#if LWIP_SNMP
- /* ifType ethernetCsmacd(6) @see RFC1213 */
- netif->link_type = 6;
- /* your link speed here */
- netif->link_speed = ;
- netif->ts = 0;
- netif->ifinoctets = 0;
- netif->ifinucastpkts = 0;
- netif->ifinnucastpkts = 0;
- netif->ifindiscards = 0;
- netif->ifoutoctets = 0;
- netif->ifoutucastpkts = 0;
- netif->ifoutnucastpkts = 0;
- netif->ifoutdiscards = 0;
-#endif
-
- netif->name[0] = IFNAME0;
- netif->name[1] = IFNAME1;
- netif->output = netfront_output;
- netif->linkoutput = low_level_output;
-
- the_interface = netif;
-
- /* set MAC hardware address */
- netif->hwaddr_len = 6;
- netif->hwaddr[0] = mac[0];
- netif->hwaddr[1] = mac[1];
- netif->hwaddr[2] = mac[2];
- netif->hwaddr[3] = mac[3];
- netif->hwaddr[4] = mac[4];
- netif->hwaddr[5] = mac[5];
-
- /* No interesting per-interface state */
- netif->state = NULL;
-
- /* maximum transfer unit */
- netif->mtu = 1500;
-
- /* broadcast capability */
- netif->flags = NETIF_FLAG_BROADCAST;
-
- etharp_init();
-
- sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
-
- return ERR_OK;
-}
-
-/*
- * Thread run by netfront: bring up the IP address and fire lwIP timers.
- */
-static __DECLARE_SEMAPHORE_GENERIC(tcpip_is_up, 0);
-static void tcpip_bringup_finished(void *p)
-{
- tprintk("TCP/IP bringup ends.\n");
- up(&tcpip_is_up);
-}
-
-/*
- * Utility function to bring the whole lot up. Call this from app_main()
- * or similar -- it starts netfront and have lwIP start its thread,
- * which calls back to tcpip_bringup_finished(), which
- * lets us know it's OK to continue.
- */
-void start_networking(void)
-{
- struct netif *netif;
- struct ip_addr ipaddr = { htonl(IF_IPADDR) };
- struct ip_addr netmask = { htonl(IF_NETMASK) };
- struct ip_addr gw = { 0 };
- char *ip = NULL;
-
- tprintk("Waiting for network.\n");
-
- dev = init_netfront(NULL, NULL, rawmac, &ip);
-
- if (ip) {
- ipaddr.addr = inet_addr(ip);
- if (IN_CLASSA(ntohl(ipaddr.addr)))
- netmask.addr = htonl(IN_CLASSA_NET);
- else if (IN_CLASSB(ntohl(ipaddr.addr)))
- netmask.addr = htonl(IN_CLASSB_NET);
- else if (IN_CLASSC(ntohl(ipaddr.addr)))
- netmask.addr = htonl(IN_CLASSC_NET);
- else
- tprintk("Strange IP %s, leaving netmask to 0.\n", ip);
- }
- tprintk("IP %x netmask %x gateway %x.\n",
- ntohl(ipaddr.addr), ntohl(netmask.addr), ntohl(gw.addr));
-
- tprintk("TCP/IP bringup begins.\n");
-
- netif = xmalloc(struct netif);
- tcpip_init(tcpip_bringup_finished, netif);
-
- netif_add(netif, &ipaddr, &netmask, &gw, rawmac,
- netif_netfront_init, ip_input);
- netif_set_default(netif);
- netif_set_up(netif);
-
- down(&tcpip_is_up);
-
- tprintk("Network is ready.\n");
-}
-
-/* Shut down the network */
-void stop_networking(void)
-{
- if (dev)
- shutdown_netfront(dev);
-}
+++ /dev/null
-/*
- * POSIX-compatible main layer
- *
- * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
- */
-
-#ifdef HAVE_LIBC
-#include <os.h>
-#include <sched.h>
-#include <console.h>
-#include <netfront.h>
-#include <pcifront.h>
-#include <time.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <xenbus.h>
-#include <events.h>
-#include <mini-os/lib.h>
-
-extern int main(int argc, char *argv[], char *envp[]);
-extern void __libc_init_array(void);
-extern void __libc_fini_array(void);
-extern unsigned long __CTOR_LIST__[];
-extern unsigned long __DTOR_LIST__[];
-
-#if 0
-#include <stdio.h>
-int main(int argc, char *argv[], char *envp[])
-{
- printf("Hello, World!\n");
- return 1;
-}
-#endif
-
-void _init(void)
-{
-}
-
-void _fini(void)
-{
-}
-
-extern char __app_bss_start, __app_bss_end;
-static void call_main(void *p)
-{
- char *c, quote;
-#ifdef CONFIG_QEMU_XS_ARGS
- char *domargs, *msg;
-#endif
- int argc;
- char **argv;
- char *envp[] = { NULL };
-#ifdef CONFIG_QEMU_XS_ARGS
- char *vm;
- char path[128];
- int domid;
-#endif
- int i;
-
- /* Let other parts initialize (including console output) before maybe
- * crashing. */
- //sleep(1);
-
-#ifdef CONFIG_SPARSE_BSS
- sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start);
-#endif
-#if defined(HAVE_LWIP) && defined(CONFIG_START_NETWORK) && defined(CONFIG_NETFRONT)
- start_networking();
-#endif
-#ifdef CONFIG_PCIFRONT
- create_thread("pcifront", pcifront_watches, NULL);
-#endif
-
-#ifdef CONFIG_QEMU_XS_ARGS
- /* Fetch argc, argv from XenStore */
- domid = xenbus_read_integer("target");
- if (domid == -1) {
- printk("Couldn't read target\n");
- do_exit();
- }
-
- snprintf(path, sizeof(path), "/local/domain/%d/vm", domid);
- msg = xenbus_read(XBT_NIL, path, &vm);
- if (msg) {
- printk("Couldn't read vm path\n");
- do_exit();
- }
- printk("dom vm is at %s\n", vm);
-
- snprintf(path, sizeof(path), "%s/image/dmargs", vm);
- free(vm);
- msg = xenbus_read(XBT_NIL, path, &domargs);
-
- if (msg) {
- printk("Couldn't get stubdom args: %s\n", msg);
- domargs = strdup("");
- }
-#endif
-
- argc = 1;
-
-#define PARSE_ARGS(ARGS,START,QUOTE,END) \
- c = ARGS; \
- quote = 0; \
- while (*c) { \
- if (*c != ' ') { \
- START; \
- while (*c) { \
- if (quote) { \
- if (*c == quote) { \
- quote = 0; \
- QUOTE; \
- continue; \
- } \
- } else if (*c == ' ') \
- break; \
- if (*c == '"' || *c == '\'') { \
- quote = *c; \
- QUOTE; \
- continue; \
- } \
- c++; \
- } \
- } else { \
- END; \
- while (*c == ' ') \
- c++; \
- } \
- } \
- if (quote) {\
- printk("Warning: unterminated quotation %c\n", quote); \
- quote = 0; \
- }
-#define PARSE_ARGS_COUNT(ARGS) PARSE_ARGS(ARGS, argc++, c++, )
-#define PARSE_ARGS_STORE(ARGS) PARSE_ARGS(ARGS, argv[argc++] = c, memmove(c, c + 1, strlen(c + 1) + 1), *c++ = 0)
-
- PARSE_ARGS_COUNT((char*)start_info.cmd_line);
-#ifdef CONFIG_QEMU_XS_ARGS
- PARSE_ARGS_COUNT(domargs);
-#endif
-
- argv = alloca((argc + 1) * sizeof(char *));
- argv[0] = "main";
- argc = 1;
-
- PARSE_ARGS_STORE((char*)start_info.cmd_line)
-#ifdef CONFIG_QEMU_XS_ARGS
- PARSE_ARGS_STORE(domargs)
-#endif
-
- argv[argc] = NULL;
-
- for (i = 0; i < argc; i++)
- printf("\"%s\" ", argv[i]);
- printf("\n");
-
- __libc_init_array();
- environ = envp;
- for (i = 0; __CTOR_LIST__[i] != 0; i++)
- ((void((*)(void)))__CTOR_LIST__[i]) ();
- tzset();
-
- exit(main(argc, argv, envp));
-}
-
-void _exit(int ret)
-{
- int i;
-
- for (i = 0; __DTOR_LIST__[i] != 0; i++)
- ((void((*)(void)))__DTOR_LIST__[i]) ();
- close_all_files();
- __libc_fini_array();
- printk("main returned %d\n", ret);
-#if defined(HAVE_LWIP) && defined(CONFIG_NETFRONT)
- stop_networking();
-#endif
- stop_kernel();
- if (!ret) {
- /* No problem, just shutdown. */
- struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
- HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
- }
- do_exit();
-}
-
-int app_main(start_info_t *si)
-{
- printk("main.c: dummy main: start_info=%p\n", si);
- main_thread = create_thread("main", call_main, si);
- return 0;
-}
-#endif
+++ /dev/null
-#
-# The file contains the common make rules for building mini-os.
-#
-
-debug = y
-
-# Define some default flags.
-# NB. '-Wcast-qual' is nasty, so I omitted it.
-DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format -Wno-redundant-decls
-DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
-DEF_CFLAGS += $(call cc-option,$(CC),-fgnu89-inline)
-DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
-DEF_CPPFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
-
-DEF_ASFLAGS += -D__ASSEMBLY__
-DEF_LDFLAGS +=
-
-ifeq ($(debug),y)
-DEF_CFLAGS += -g
-#DEF_CFLAGS += -DMM_DEBUG
-#DEF_CFLAGS += -DFS_DEBUG
-#DEF_CFLAGS += -DLIBC_DEBUG
-#DEF_CFLAGS += -DGNT_DEBUG
-#DEF_CFLAGS += -DGNTMAP_DEBUG
-else
-DEF_CFLAGS += -O3
-endif
-
-# Make the headers define our internal stuff
-DEF_CFLAGS += -D__INSIDE_MINIOS__
-
-# Build the CFLAGS and ASFLAGS for compiling and assembling.
-# DEF_... flags are the common mini-os flags,
-# ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
-CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
-CPPFLAGS := $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS)
-ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
-LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
-
-# Special build dependencies.
-# Rebuild all after touching this/these file(s)
-EXTRA_DEPS += $(MINI-OS_ROOT)/minios.mk
-EXTRA_DEPS += $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
-
-# Find all header files for checking dependencies.
-HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h)
-HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h)
-HDRS += $(wildcard $(ARCH_INC)/*.h)
-# For special wanted header directories.
-extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
-HDRS += $(extra_heads)
-
-# Add the special header directories to the include paths.
-override CPPFLAGS := $(CPPFLAGS) $(extra_incl)
-
-# The name of the architecture specific library.
-# This is on x86_32: libx86_32.a
-# $(ARCH_LIB) has to built in the architecture specific directory.
-ARCH_LIB_NAME = $(MINIOS_TARGET_ARCH)
-ARCH_LIB := lib$(ARCH_LIB_NAME).a
-
-# This object contains the entrypoint for startup from Xen.
-# $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
-HEAD_ARCH_OBJ := $(MINIOS_TARGET_ARCH).o
-HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
-
-
-$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
- $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-
-$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
- $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
-
-
-
-
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: mm.c
- * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- * Changes: Grzegorz Milos
- *
- * Date: Aug 2003, chages Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: memory management related functions
- * contains buddy page allocator from Xen.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <xen/memory.h>
-#include <mini-os/mm.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-
-#ifdef MM_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-/*********************
- * ALLOCATION BITMAP
- * One bit per page of memory. Bit set => page is allocated.
- */
-
-static unsigned long *alloc_bitmap;
-#define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
-
-#define allocated_in_map(_pn) \
-(alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & (1UL<<((_pn)&(PAGES_PER_MAPWORD-1))))
-
-/*
- * Hint regarding bitwise arithmetic in map_{alloc,free}:
- * -(1<<n) sets all bits >= n.
- * (1<<n)-1 sets all bits < n.
- * Variable names in map_{alloc,free}:
- * *_idx == Index into `alloc_bitmap' array.
- * *_off == Bit offset within an element of the `alloc_bitmap' array.
- */
-
-static void map_alloc(unsigned long first_page, unsigned long nr_pages)
-{
- unsigned long start_off, end_off, curr_idx, end_idx;
-
- curr_idx = first_page / PAGES_PER_MAPWORD;
- start_off = first_page & (PAGES_PER_MAPWORD-1);
- end_idx = (first_page + nr_pages) / PAGES_PER_MAPWORD;
- end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD-1);
-
- if ( curr_idx == end_idx )
- {
- alloc_bitmap[curr_idx] |= ((1UL<<end_off)-1) & -(1UL<<start_off);
- }
- else
- {
- alloc_bitmap[curr_idx] |= -(1UL<<start_off);
- while ( ++curr_idx < end_idx ) alloc_bitmap[curr_idx] = ~0UL;
- alloc_bitmap[curr_idx] |= (1UL<<end_off)-1;
- }
-}
-
-
-static void map_free(unsigned long first_page, unsigned long nr_pages)
-{
- unsigned long start_off, end_off, curr_idx, end_idx;
-
- curr_idx = first_page / PAGES_PER_MAPWORD;
- start_off = first_page & (PAGES_PER_MAPWORD-1);
- end_idx = (first_page + nr_pages) / PAGES_PER_MAPWORD;
- end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD-1);
-
- if ( curr_idx == end_idx )
- {
- alloc_bitmap[curr_idx] &= -(1UL<<end_off) | ((1UL<<start_off)-1);
- }
- else
- {
- alloc_bitmap[curr_idx] &= (1UL<<start_off)-1;
- while ( ++curr_idx != end_idx ) alloc_bitmap[curr_idx] = 0;
- alloc_bitmap[curr_idx] &= -(1UL<<end_off);
- }
-}
-
-
-
-/*************************
- * BINARY BUDDY ALLOCATOR
- */
-
-typedef struct chunk_head_st chunk_head_t;
-typedef struct chunk_tail_st chunk_tail_t;
-
-struct chunk_head_st {
- chunk_head_t *next;
- chunk_head_t **pprev;
- int level;
-};
-
-struct chunk_tail_st {
- int level;
-};
-
-/* Linked lists of free chunks of different powers-of-two in size. */
-#define FREELIST_SIZE ((sizeof(void*)<<3)-PAGE_SHIFT)
-static chunk_head_t *free_head[FREELIST_SIZE];
-static chunk_head_t free_tail[FREELIST_SIZE];
-#define FREELIST_EMPTY(_l) ((_l)->next == NULL)
-
-#define round_pgdown(_p) ((_p)&PAGE_MASK)
-#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-
-#ifdef MM_DEBUG
-/*
- * Prints allocation[0/1] for @nr_pages, starting at @start
- * address (virtual).
- */
-USED static void print_allocation(void *start, int nr_pages)
-{
- unsigned long pfn_start = virt_to_pfn(start);
- int count;
- for(count = 0; count < nr_pages; count++)
- if(allocated_in_map(pfn_start + count)) printk("1");
- else printk("0");
-
- printk("\n");
-}
-
-/*
- * Prints chunks (making them with letters) for @nr_pages starting
- * at @start (virtual).
- */
-USED static void print_chunks(void *start, int nr_pages)
-{
- char chunks[1001], current='A';
- int order, count;
- chunk_head_t *head;
- unsigned long pfn_start = virt_to_pfn(start);
-
- memset(chunks, (int)'_', 1000);
- if(nr_pages > 1000)
- {
- DEBUG("Can only pring 1000 pages. Increase buffer size.");
- }
-
- for(order=0; order < FREELIST_SIZE; order++)
- {
- head = free_head[order];
- while(!FREELIST_EMPTY(head))
- {
- for(count = 0; count < 1UL<< head->level; count++)
- {
- if(count + virt_to_pfn(head) - pfn_start < 1000)
- chunks[count + virt_to_pfn(head) - pfn_start] = current;
- }
- head = head->next;
- current++;
- }
- }
- chunks[nr_pages] = '\0';
- printk("%s\n", chunks);
-}
-#endif
-
-
-/*
- * Initialise allocator, placing addresses [@min,@max] in free pool.
- * @min and @max are PHYSICAL addresses.
- */
-static void init_page_allocator(unsigned long min, unsigned long max)
-{
- int i;
- unsigned long range, bitmap_size;
- chunk_head_t *ch;
- chunk_tail_t *ct;
- for ( i = 0; i < FREELIST_SIZE; i++ )
- {
- free_head[i] = &free_tail[i];
- free_tail[i].pprev = &free_head[i];
- free_tail[i].next = NULL;
- }
-
- min = round_pgup (min);
- max = round_pgdown(max);
-
- /* Allocate space for the allocation bitmap. */
- bitmap_size = (max+1) >> (PAGE_SHIFT+3);
- bitmap_size = round_pgup(bitmap_size);
- alloc_bitmap = (unsigned long *)to_virt(min);
- min += bitmap_size;
- range = max - min;
-
- /* All allocated by default. */
- memset(alloc_bitmap, ~0, bitmap_size);
- /* Free up the memory we've been given to play with. */
- map_free(PHYS_PFN(min), range>>PAGE_SHIFT);
-
- /* The buddy lists are addressed in high memory. */
- min = (unsigned long) to_virt(min);
- max = (unsigned long) to_virt(max);
-
- while ( range != 0 )
- {
- /*
- * Next chunk is limited by alignment of min, but also
- * must not be bigger than remaining range.
- */
- for ( i = PAGE_SHIFT; (1UL<<(i+1)) <= range; i++ )
- if ( min & (1UL<<i) ) break;
-
-
- ch = (chunk_head_t *)min;
- min += (1UL<<i);
- range -= (1UL<<i);
- ct = (chunk_tail_t *)min-1;
- i -= PAGE_SHIFT;
- ch->level = i;
- ch->next = free_head[i];
- ch->pprev = &free_head[i];
- ch->next->pprev = &ch->next;
- free_head[i] = ch;
- ct->level = i;
- }
-}
-
-
-/* Allocate 2^@order contiguous pages. Returns a VIRTUAL address. */
-unsigned long alloc_pages(int order)
-{
- int i;
- chunk_head_t *alloc_ch, *spare_ch;
- chunk_tail_t *spare_ct;
-
-
- /* Find smallest order which can satisfy the request. */
- for ( i = order; i < FREELIST_SIZE; i++ ) {
- if ( !FREELIST_EMPTY(free_head[i]) )
- break;
- }
-
- if ( i == FREELIST_SIZE ) goto no_memory;
-
- /* Unlink a chunk. */
- alloc_ch = free_head[i];
- free_head[i] = alloc_ch->next;
- alloc_ch->next->pprev = alloc_ch->pprev;
-
- /* We may have to break the chunk a number of times. */
- while ( i != order )
- {
- /* Split into two equal parts. */
- i--;
- spare_ch = (chunk_head_t *)((char *)alloc_ch + (1UL<<(i+PAGE_SHIFT)));
- spare_ct = (chunk_tail_t *)((char *)spare_ch + (1UL<<(i+PAGE_SHIFT)))-1;
-
- /* Create new header for spare chunk. */
- spare_ch->level = i;
- spare_ch->next = free_head[i];
- spare_ch->pprev = &free_head[i];
- spare_ct->level = i;
-
- /* Link in the spare chunk. */
- spare_ch->next->pprev = &spare_ch->next;
- free_head[i] = spare_ch;
- }
-
- map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1UL<<order);
-
- return((unsigned long)alloc_ch);
-
- no_memory:
-
- printk("Cannot handle page request order %d!\n", order);
-
- return 0;
-}
-
-void free_pages(void *pointer, int order)
-{
- chunk_head_t *freed_ch, *to_merge_ch;
- chunk_tail_t *freed_ct;
- unsigned long mask;
-
- /* First free the chunk */
- map_free(virt_to_pfn(pointer), 1UL << order);
-
- /* Create free chunk */
- freed_ch = (chunk_head_t *)pointer;
- freed_ct = (chunk_tail_t *)((char *)pointer + (1UL<<(order + PAGE_SHIFT)))-1;
-
- /* Now, possibly we can conseal chunks together */
- while(order < FREELIST_SIZE)
- {
- mask = 1UL << (order + PAGE_SHIFT);
- if((unsigned long)freed_ch & mask)
- {
- to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask);
- if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
- to_merge_ch->level != order)
- break;
-
- /* Merge with predecessor */
- freed_ch = to_merge_ch;
- }
- else
- {
- to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask);
- if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
- to_merge_ch->level != order)
- break;
-
- /* Merge with successor */
- freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask) - 1;
- }
-
- /* We are commited to merging, unlink the chunk */
- *(to_merge_ch->pprev) = to_merge_ch->next;
- to_merge_ch->next->pprev = to_merge_ch->pprev;
-
- order++;
- }
-
- /* Link the new chunk */
- freed_ch->level = order;
- freed_ch->next = free_head[order];
- freed_ch->pprev = &free_head[order];
- freed_ct->level = order;
-
- freed_ch->next->pprev = &freed_ch->next;
- free_head[order] = freed_ch;
-
-}
-
-int free_physical_pages(xen_pfn_t *mfns, int n)
-{
- struct xen_memory_reservation reservation;
-
- set_xen_guest_handle(reservation.extent_start, mfns);
- reservation.nr_extents = n;
- reservation.extent_order = 0;
- reservation.domid = DOMID_SELF;
- return HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
-}
-
-#ifdef HAVE_LIBC
-void *sbrk(ptrdiff_t increment)
-{
- unsigned long old_brk = brk;
- unsigned long new_brk = old_brk + increment;
-
- if (new_brk > heap_end) {
- printk("Heap exhausted: %p + %lx = %p > %p\n", old_brk, increment, new_brk, heap_end);
- return NULL;
- }
-
- if (new_brk > heap_mapped) {
- unsigned long n = (new_brk - heap_mapped + PAGE_SIZE - 1) / PAGE_SIZE;
- do_map_zero(heap_mapped, n);
- heap_mapped += n * PAGE_SIZE;
- }
-
- brk = new_brk;
-
- return (void *) old_brk;
-}
-#endif
-
-
-
-void init_mm(void)
-{
-
- unsigned long start_pfn, max_pfn;
-
- printk("MM: Init\n");
-
- arch_init_mm(&start_pfn, &max_pfn);
- /*
- * now we can initialise the page allocator
- */
- printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
- (u_long)to_virt(PFN_PHYS(start_pfn)), (u_long)PFN_PHYS(start_pfn),
- (u_long)to_virt(PFN_PHYS(max_pfn)), (u_long)PFN_PHYS(max_pfn));
- init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
- printk("MM: done\n");
-
- arch_init_p2m(max_pfn);
-
- arch_init_demand_mapping_area(max_pfn);
-}
-
-void fini_mm(void)
-{
-}
-
-void sanity_check(void)
-{
- int x;
- chunk_head_t *head;
-
- for (x = 0; x < FREELIST_SIZE; x++) {
- for (head = free_head[x]; !FREELIST_EMPTY(head); head = head->next) {
- ASSERT(!allocated_in_map(virt_to_pfn(head)));
- if (head->next)
- ASSERT(head->next->pprev == &head->next);
- }
- if (free_head[x]) {
- ASSERT(free_head[x]->pprev == &free_head[x]);
- }
- }
-}
+++ /dev/null
-/* Minimal network driver for Mini-OS.
- * Copyright (c) 2006-2007 Jacob Gorm Hansen, University of Copenhagen.
- * Based on netfront.c from Xen Linux.
- *
- * Does not handle fragments or extras.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <errno.h>
-#include <xen/io/netif.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/time.h>
-#include <mini-os/netfront.h>
-#include <mini-os/lib.h>
-#include <mini-os/semaphore.h>
-
-DECLARE_WAIT_QUEUE_HEAD(netfront_queue);
-
-#ifdef HAVE_LIBC
-#define NETIF_SELECT_RX ((void*)-1)
-#endif
-
-
-
-#define NET_TX_RING_SIZE __CONST_RING_SIZE(netif_tx, PAGE_SIZE)
-#define NET_RX_RING_SIZE __CONST_RING_SIZE(netif_rx, PAGE_SIZE)
-#define GRANT_INVALID_REF 0
-
-
-struct net_buffer {
- void* page;
- grant_ref_t gref;
-};
-
-struct netfront_dev {
- domid_t dom;
-
- unsigned short tx_freelist[NET_TX_RING_SIZE + 1];
- struct semaphore tx_sem;
-
- struct net_buffer rx_buffers[NET_RX_RING_SIZE];
- struct net_buffer tx_buffers[NET_TX_RING_SIZE];
-
- struct netif_tx_front_ring tx;
- struct netif_rx_front_ring rx;
- grant_ref_t tx_ring_ref;
- grant_ref_t rx_ring_ref;
- evtchn_port_t evtchn;
-
- char *nodename;
- char *backend;
- char *mac;
-
- xenbus_event_queue events;
-
-#ifdef HAVE_LIBC
- int fd;
- unsigned char *data;
- size_t len;
- size_t rlen;
-#endif
-
- void (*netif_rx)(unsigned char* data, int len);
-};
-
-void init_rx_buffers(struct netfront_dev *dev);
-
-static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
-{
- freelist[id + 1] = freelist[0];
- freelist[0] = id;
-}
-
-static inline unsigned short get_id_from_freelist(unsigned short* freelist)
-{
- unsigned int id = freelist[0];
- freelist[0] = freelist[id + 1];
- return id;
-}
-
-__attribute__((weak)) void netif_rx(unsigned char* data,int len)
-{
- printk("%d bytes incoming at %p\n",len,data);
-}
-
-__attribute__((weak)) void net_app_main(void*si,unsigned char*mac) {}
-
-static inline int xennet_rxidx(RING_IDX idx)
-{
- return idx & (NET_RX_RING_SIZE - 1);
-}
-
-void network_rx(struct netfront_dev *dev)
-{
- RING_IDX rp,cons,req_prod;
- int nr_consumed, more, i, notify;
-#ifdef HAVE_LIBC
- int some;
-#endif
-
- nr_consumed = 0;
-moretodo:
- rp = dev->rx.sring->rsp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
-
-#ifdef HAVE_LIBC
- some = 0;
-#endif
- for (cons = dev->rx.rsp_cons; cons != rp; nr_consumed++, cons++)
- {
- struct net_buffer* buf;
- unsigned char* page;
- int id;
-
- struct netif_rx_response *rx = RING_GET_RESPONSE(&dev->rx, cons);
-
- id = rx->id;
- BUG_ON(id >= NET_RX_RING_SIZE);
-
- buf = &dev->rx_buffers[id];
- page = (unsigned char*)buf->page;
- gnttab_end_access(buf->gref);
-
- if (rx->status > NETIF_RSP_NULL)
- {
-#ifdef HAVE_LIBC
- if (dev->netif_rx == NETIF_SELECT_RX) {
- int len = rx->status;
- ASSERT(current == main_thread);
- if (len > dev->len)
- len = dev->len;
- memcpy(dev->data, page+rx->offset, len);
- dev->rlen = len;
- some = 1;
- break;
- } else
-#endif
- dev->netif_rx(page+rx->offset,rx->status);
- }
- }
- dev->rx.rsp_cons=cons;
-
- RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
-#ifdef HAVE_LIBC
- if(more && !some) goto moretodo;
-#else
- if(more) goto moretodo;
-#endif
-
- req_prod = dev->rx.req_prod_pvt;
-
- for(i=0; i<nr_consumed; i++)
- {
- int id = xennet_rxidx(req_prod + i);
- netif_rx_request_t *req = RING_GET_REQUEST(&dev->rx, req_prod + i);
- struct net_buffer* buf = &dev->rx_buffers[id];
- void* page = buf->page;
-
- /* We are sure to have free gnttab entries since they got released above */
- buf->gref = req->gref =
- gnttab_grant_access(dev->dom,virt_to_mfn(page),0);
-
- req->id = id;
- }
-
- wmb();
-
- dev->rx.req_prod_pvt = req_prod + i;
-
- RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
- if (notify)
- notify_remote_via_evtchn(dev->evtchn);
-
-}
-
-void network_tx_buf_gc(struct netfront_dev *dev)
-{
-
-
- RING_IDX cons, prod;
- unsigned short id;
-
- do {
- prod = dev->tx.sring->rsp_prod;
- rmb(); /* Ensure we see responses up to 'rp'. */
-
- for (cons = dev->tx.rsp_cons; cons != prod; cons++)
- {
- struct netif_tx_response *txrsp;
- struct net_buffer *buf;
-
- txrsp = RING_GET_RESPONSE(&dev->tx, cons);
- if (txrsp->status == NETIF_RSP_NULL)
- continue;
-
- if (txrsp->status == NETIF_RSP_ERROR)
- printk("packet error\n");
-
- id = txrsp->id;
- BUG_ON(id >= NET_TX_RING_SIZE);
- buf = &dev->tx_buffers[id];
- gnttab_end_access(buf->gref);
- buf->gref=GRANT_INVALID_REF;
-
- add_id_to_freelist(id,dev->tx_freelist);
- up(&dev->tx_sem);
- }
-
- dev->tx.rsp_cons = prod;
-
- /*
- * Set a new event, then check for race with update of tx_cons.
- * Note that it is essential to schedule a callback, no matter
- * how few tx_buffers are pending. Even if there is space in the
- * transmit ring, higher layers may be blocked because too much
- * data is outstanding: in such cases notification from Xen is
- * likely to be the only kick that we'll get.
- */
- dev->tx.sring->rsp_event =
- prod + ((dev->tx.sring->req_prod - prod) >> 1) + 1;
- mb();
- } while ((cons == prod) && (prod != dev->tx.sring->rsp_prod));
-
-
-}
-
-void netfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
- int flags;
- struct netfront_dev *dev = data;
-
- local_irq_save(flags);
-
- network_tx_buf_gc(dev);
- network_rx(dev);
-
- local_irq_restore(flags);
-}
-
-#ifdef HAVE_LIBC
-void netfront_select_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
- int flags;
- struct netfront_dev *dev = data;
- int fd = dev->fd;
-
- local_irq_save(flags);
- network_tx_buf_gc(dev);
- local_irq_restore(flags);
-
- if (fd != -1)
- files[fd].read = 1;
- wake_up(&netfront_queue);
-}
-#endif
-
-static void free_netfront(struct netfront_dev *dev)
-{
- int i;
-
- for(i=0;i<NET_TX_RING_SIZE;i++)
- down(&dev->tx_sem);
-
- mask_evtchn(dev->evtchn);
-
- free(dev->mac);
- free(dev->backend);
-
- gnttab_end_access(dev->rx_ring_ref);
- gnttab_end_access(dev->tx_ring_ref);
-
- free_page(dev->rx.sring);
- free_page(dev->tx.sring);
-
- unbind_evtchn(dev->evtchn);
-
- for(i=0;i<NET_RX_RING_SIZE;i++) {
- gnttab_end_access(dev->rx_buffers[i].gref);
- free_page(dev->rx_buffers[i].page);
- }
-
- for(i=0;i<NET_TX_RING_SIZE;i++)
- if (dev->tx_buffers[i].page)
- free_page(dev->tx_buffers[i].page);
-
- free(dev->nodename);
- free(dev);
-}
-
-struct netfront_dev *init_netfront(char *_nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6], char **ip)
-{
- xenbus_transaction_t xbt;
- char* err;
- char* message=NULL;
- struct netif_tx_sring *txs;
- struct netif_rx_sring *rxs;
- int retry=0;
- int i;
- char* msg = NULL;
- char nodename[256];
- char path[256];
- struct netfront_dev *dev;
- static int netfrontends = 0;
-
- if (!_nodename)
- snprintf(nodename, sizeof(nodename), "device/vif/%d", netfrontends);
- else {
- strncpy(nodename, _nodename, sizeof(nodename) - 1);
- nodename[sizeof(nodename) - 1] = 0;
- }
- netfrontends++;
-
- if (!thenetif_rx)
- thenetif_rx = netif_rx;
-
- printk("************************ NETFRONT for %s **********\n\n\n", nodename);
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- printk("net TX ring size %d\n", NET_TX_RING_SIZE);
- printk("net RX ring size %d\n", NET_RX_RING_SIZE);
- init_SEMAPHORE(&dev->tx_sem, NET_TX_RING_SIZE);
- for(i=0;i<NET_TX_RING_SIZE;i++)
- {
- add_id_to_freelist(i,dev->tx_freelist);
- dev->tx_buffers[i].page = NULL;
- }
-
- for(i=0;i<NET_RX_RING_SIZE;i++)
- {
- /* TODO: that's a lot of memory */
- dev->rx_buffers[i].page = (char*)alloc_page();
- }
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- dev->dom = xenbus_read_integer(path);
-#ifdef HAVE_LIBC
- if (thenetif_rx == NETIF_SELECT_RX)
- evtchn_alloc_unbound(dev->dom, netfront_select_handler, dev, &dev->evtchn);
- else
-#endif
- evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn);
-
- txs = (struct netif_tx_sring *) alloc_page();
- rxs = (struct netif_rx_sring *) alloc_page();
- memset(txs,0,PAGE_SIZE);
- memset(rxs,0,PAGE_SIZE);
-
-
- SHARED_RING_INIT(txs);
- SHARED_RING_INIT(rxs);
- FRONT_RING_INIT(&dev->tx, txs, PAGE_SIZE);
- FRONT_RING_INIT(&dev->rx, rxs, PAGE_SIZE);
-
- dev->tx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(txs),0);
- dev->rx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(rxs),0);
-
- init_rx_buffers(dev);
-
- dev->netif_rx = thenetif_rx;
-
- dev->events = NULL;
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "tx-ring-ref","%u",
- dev->tx_ring_ref);
- if (err) {
- message = "writing tx ring-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename, "rx-ring-ref","%u",
- dev->rx_ring_ref);
- if (err) {
- message = "writing rx ring-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "event-channel", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
-
- err = xenbus_printf(xbt, nodename, "request-rx-copy", "%u", 1);
-
- if (err) {
- message = "writing request-rx-copy";
- goto abort_transaction;
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateConnected);
- if (err) {
- message = "switching state";
- goto abort_transaction;
- }
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- snprintf(path, sizeof(path), "%s/mac", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->mac);
-
- if ((dev->backend == NULL) || (dev->mac == NULL)) {
- printk("%s: backend/mac failed\n", __func__);
- goto error;
- }
-
- printk("backend at %s\n",dev->backend);
- printk("mac is %s\n",dev->mac);
-
- {
- XenbusState state;
- char path[strlen(dev->backend) + strlen("/state") + 1];
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
- err = NULL;
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateConnected)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (state != XenbusStateConnected) {
- printk("backend not avalable, state=%d\n", state);
- xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
-
- if (ip) {
- snprintf(path, sizeof(path), "%s/ip", dev->backend);
- xenbus_read(XBT_NIL, path, ip);
- }
- }
-
- printk("**************************\n");
-
- unmask_evtchn(dev->evtchn);
-
- /* Special conversion specifier 'hh' needed for __ia64__. Without
- this mini-os panics with 'Unaligned reference'. */
- if (rawmac)
- sscanf(dev->mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &rawmac[0],
- &rawmac[1],
- &rawmac[2],
- &rawmac[3],
- &rawmac[4],
- &rawmac[5]);
-
- return dev;
-error:
- free(msg);
- free(err);
- free_netfront(dev);
- return NULL;
-}
-
-#ifdef HAVE_LIBC
-int netfront_tap_open(char *nodename) {
- struct netfront_dev *dev;
-
- dev = init_netfront(nodename, NETIF_SELECT_RX, NULL, NULL);
- if (!dev) {
- printk("TAP open failed\n");
- errno = EIO;
- return -1;
- }
- dev->fd = alloc_fd(FTYPE_TAP);
- printk("tap_open(%s) -> %d\n", nodename, dev->fd);
- files[dev->fd].tap.dev = dev;
- return dev->fd;
-}
-#endif
-
-void shutdown_netfront(struct netfront_dev *dev)
-{
- char* err = NULL, *err2;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/request-rx-copy") + 1];
-
- printk("close network: backend at %s\n",dev->backend);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("shutdown_netfront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("shutdown_netfront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (state < XenbusStateClosed) {
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
- }
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
- printk("shutdown_netfront: error changing state to %d: %s\n",
- XenbusStateInitialising, err);
- goto close;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
-
-close:
- free(err);
- err2 = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err2);
-
- snprintf(nodename, sizeof(nodename), "%s/tx-ring-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/rx-ring-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/request-rx-copy", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
-
- if (!err)
- free_netfront(dev);
-}
-
-
-void init_rx_buffers(struct netfront_dev *dev)
-{
- int i, requeue_idx;
- netif_rx_request_t *req;
- int notify;
-
- /* Rebuild the RX buffer freelist and the RX ring itself. */
- for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++)
- {
- struct net_buffer* buf = &dev->rx_buffers[requeue_idx];
- req = RING_GET_REQUEST(&dev->rx, requeue_idx);
-
- buf->gref = req->gref =
- gnttab_grant_access(dev->dom,virt_to_mfn(buf->page),0);
-
- req->id = requeue_idx;
-
- requeue_idx++;
- }
-
- dev->rx.req_prod_pvt = requeue_idx;
-
- RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
-
- if (notify)
- notify_remote_via_evtchn(dev->evtchn);
-
- dev->rx.sring->rsp_event = dev->rx.rsp_cons + 1;
-}
-
-
-void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len)
-{
- int flags;
- struct netif_tx_request *tx;
- RING_IDX i;
- int notify;
- unsigned short id;
- struct net_buffer* buf;
- void* page;
-
- BUG_ON(len > PAGE_SIZE);
-
- down(&dev->tx_sem);
-
- local_irq_save(flags);
- id = get_id_from_freelist(dev->tx_freelist);
- local_irq_restore(flags);
-
- buf = &dev->tx_buffers[id];
- page = buf->page;
- if (!page)
- page = buf->page = (char*) alloc_page();
-
- i = dev->tx.req_prod_pvt;
- tx = RING_GET_REQUEST(&dev->tx, i);
-
- memcpy(page,data,len);
-
- buf->gref =
- tx->gref = gnttab_grant_access(dev->dom,virt_to_mfn(page),1);
-
- tx->offset=0;
- tx->size = len;
- tx->flags=0;
- tx->id = id;
- dev->tx.req_prod_pvt = i + 1;
-
- wmb();
-
- RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->tx, notify);
-
- if(notify) notify_remote_via_evtchn(dev->evtchn);
-
- local_irq_save(flags);
- network_tx_buf_gc(dev);
- local_irq_restore(flags);
-}
-
-#ifdef HAVE_LIBC
-ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len)
-{
- unsigned long flags;
- int fd = dev->fd;
- ASSERT(current == main_thread);
-
- dev->rlen = 0;
- dev->data = data;
- dev->len = len;
-
- local_irq_save(flags);
- network_rx(dev);
- if (!dev->rlen && fd != -1)
- /* No data for us, make select stop returning */
- files[fd].read = 0;
- /* Before re-enabling the interrupts, in case a packet just arrived in the
- * meanwhile. */
- local_irq_restore(flags);
-
- dev->data = NULL;
- dev->len = 0;
-
- return dev->rlen;
-}
-#endif
+++ /dev/null
-/* Minimal PCI driver for Mini-OS.
- * Copyright (c) 2007-2008 Samuel Thibault.
- * Based on blkfront.c.
- */
-
-#include <string.h>
-#include <mini-os/os.h>
-#include <mini-os/lib.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <errno.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/wait.h>
-#include <mini-os/pcifront.h>
-#include <mini-os/sched.h>
-
-#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
-
-DECLARE_WAIT_QUEUE_HEAD(pcifront_queue);
-static struct pcifront_dev *pcidev;
-
-struct pcifront_dev {
- domid_t dom;
-
- struct xen_pci_sharedinfo *info;
- grant_ref_t info_ref;
- evtchn_port_t evtchn;
-
- char *nodename;
- char *backend;
-
- xenbus_event_queue events;
-};
-
-void pcifront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
- wake_up(&pcifront_queue);
-}
-
-static void free_pcifront(struct pcifront_dev *dev)
-{
- if (!dev)
- dev = pcidev;
-
- mask_evtchn(dev->evtchn);
-
- gnttab_end_access(dev->info_ref);
- free_page(dev->info);
-
- unbind_evtchn(dev->evtchn);
-
- free(dev->backend);
- free(dev->nodename);
- free(dev);
-}
-
-void pcifront_watches(void *opaque)
-{
- XenbusState state;
- char *err = NULL, *msg = NULL;
- char *be_path, *be_state;
- char* nodename = opaque ? opaque : "device/pci/0";
- char path[strlen(nodename) + 9];
- char fe_state[strlen(nodename) + 7];
- xenbus_event_queue events = NULL;
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- snprintf(fe_state, sizeof(fe_state), "%s/state", nodename);
-
- while (1) {
- printk("pcifront_watches: waiting for backend path to appear %s\n", path);
- xenbus_watch_path_token(XBT_NIL, path, path, &events);
- while ((err = xenbus_read(XBT_NIL, path, &be_path)) != NULL) {
- free(err);
- xenbus_wait_for_watch(&events);
- }
- xenbus_unwatch_path_token(XBT_NIL, path, path);
- printk("pcifront_watches: waiting for backend to get into the right state %s\n", be_path);
- be_state = (char *) malloc(strlen(be_path) + 7);
- snprintf(be_state, strlen(be_path) + 7, "%s/state", be_path);
- xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events);
- while ((err = xenbus_read(XBT_NIL, be_state, &msg)) != NULL || msg[0] > '4') {
- free(msg);
- free(err);
- xenbus_wait_for_watch(&events);
- }
- xenbus_unwatch_path_token(XBT_NIL, be_state, be_state);
- if (init_pcifront(NULL) == NULL) {
- free(be_state);
- free(be_path);
- continue;
- }
- xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events);
- state = XenbusStateConnected;
- printk("pcifront_watches: waiting for backend events %s\n", be_state);
- while ((err = xenbus_wait_for_state_change(be_state, &state, &events)) == NULL &&
- (err = xenbus_read(XBT_NIL, pcidev->backend, &msg)) == NULL) {
- free(msg);
- printk("pcifront_watches: backend state changed: %s %d\n", be_state, state);
- if (state == XenbusStateReconfiguring) {
- printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateReconfiguring);
- if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateReconfiguring)) != NULL) {
- printk("pcifront_watches: error changing state to %d: %s\n",
- XenbusStateReconfiguring, err);
- if (!strcmp(err, "ENOENT")) {
- xenbus_write(XBT_NIL, fe_state, "7");
- free(err);
- }
- }
- } else if (state == XenbusStateReconfigured) {
- printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateConnected);
- printk("pcifront_watches: changing state to %d\n", XenbusStateConnected);
- if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateConnected)) != NULL) {
- printk("pcifront_watches: error changing state to %d: %s\n",
- XenbusStateConnected, err);
- if (!strcmp(err, "ENOENT")) {
- xenbus_write(XBT_NIL, fe_state, "4");
- free(err);
- }
- }
- } else if (state == XenbusStateClosing)
- break;
- }
- if (err) {
- printk("pcifront_watches: done waiting err=%s\n", err);
- free(err);
- } else
- printk("pcifront_watches: done waiting\n");
- err = xenbus_unwatch_path_token(XBT_NIL, be_state, be_state);
- shutdown_pcifront(pcidev);
- free(be_state);
- free(be_path);
- free(err);
- pcidev = NULL;
- }
-
- xenbus_unwatch_path_token(XBT_NIL, path, path);
-}
-
-struct pcifront_dev *init_pcifront(char *_nodename)
-{
- xenbus_transaction_t xbt;
- char* err;
- char* message=NULL;
- int retry=0;
- char* msg = NULL;
- char* nodename = _nodename ? _nodename : "device/pci/0";
- int dom;
-
- struct pcifront_dev *dev;
-
- char path[strlen(nodename) + strlen("/backend-id") + 1];
-
- if (!_nodename && pcidev)
- return pcidev;
-
- printk("******************* PCIFRONT for %s **********\n\n\n", nodename);
-
- snprintf(path, sizeof(path), "%s/backend-id", nodename);
- dom = xenbus_read_integer(path);
- if (dom == -1) {
- printk("no backend\n");
- return NULL;
- }
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->nodename = strdup(nodename);
- dev->dom = dom;
-
- evtchn_alloc_unbound(dev->dom, pcifront_handler, dev, &dev->evtchn);
-
- dev->info = (struct xen_pci_sharedinfo*) alloc_page();
- memset(dev->info,0,PAGE_SIZE);
-
- dev->info_ref = gnttab_grant_access(dev->dom,virt_to_mfn(dev->info),0);
-
- dev->events = NULL;
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- printk("starting transaction\n");
- free(err);
- }
-
- err = xenbus_printf(xbt, nodename, "pci-op-ref","%u",
- dev->info_ref);
- if (err) {
- message = "writing pci-op-ref";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "event-channel", "%u", dev->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
- err = xenbus_printf(xbt, nodename,
- "magic", XEN_PCI_MAGIC);
- if (err) {
- message = "writing magic";
- goto abort_transaction;
- }
-
- snprintf(path, sizeof(path), "%s/state", nodename);
- err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
- if (err) {
- message = "switching state";
- goto abort_transaction;
- }
-
- err = xenbus_transaction_end(xbt, 0, &retry);
- free(err);
- if (retry) {
- goto again;
- printk("completing transaction\n");
- }
-
- goto done;
-
-abort_transaction:
- free(err);
- err = xenbus_transaction_end(xbt, 1, &retry);
- printk("Abort transaction %s\n", message);
- goto error;
-
-done:
-
- snprintf(path, sizeof(path), "%s/backend", nodename);
- msg = xenbus_read(XBT_NIL, path, &dev->backend);
- if (msg) {
- printk("Error %s when reading the backend path %s\n", msg, path);
- goto error;
- }
-
- printk("backend at %s\n", dev->backend);
-
- {
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char frontpath[strlen(nodename) + strlen("/state") + 1];
- XenbusState state;
- snprintf(path, sizeof(path), "%s/state", dev->backend);
-
- xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
- err = NULL;
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateConnected)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- if (state != XenbusStateConnected) {
- printk("backend not avalable, state=%d\n", state);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
-
- snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
- if ((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected))
- != NULL) {
- printk("error switching state %s\n", err);
- free(err);
- err = xenbus_unwatch_path_token(XBT_NIL, path, path);
- goto error;
- }
- }
- unmask_evtchn(dev->evtchn);
-
- printk("**************************\n");
-
- if (!_nodename)
- pcidev = dev;
-
- return dev;
-
-error:
- free(msg);
- free(err);
- free_pcifront(dev);
- return NULL;
-}
-
-void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun))
-{
- char *path;
- int i, n, len;
- char *s, *msg = NULL;
- unsigned int domain, bus, slot, fun;
-
- if (!dev)
- dev = pcidev;
- if (!dev) {
- printk("pcifront_scan: device or bus\n");
- return;
- }
-
- len = strlen(dev->backend) + 1 + 5 + 10 + 1;
- path = (char *) malloc(len);
- snprintf(path, len, "%s/num_devs", dev->backend);
- n = xenbus_read_integer(path);
-
- for (i = 0; i < n; i++) {
- snprintf(path, len, "%s/dev-%d", dev->backend, i);
- msg = xenbus_read(XBT_NIL, path, &s);
- if (msg) {
- printk("Error %s when reading the PCI root name at %s\n", msg, path);
- free(msg);
- continue;
- }
-
- if (sscanf(s, "%x:%x:%x.%x", &domain, &bus, &slot, &fun) != 4) {
- printk("\"%s\" does not look like a PCI device address\n", s);
- free(s);
- continue;
- }
- free(s);
-
- if (func)
- func(domain, bus, slot, fun);
- }
- free(path);
-}
-
-void shutdown_pcifront(struct pcifront_dev *dev)
-{
- char* err = NULL, *err2;
- XenbusState state;
-
- char path[strlen(dev->backend) + strlen("/state") + 1];
- char nodename[strlen(dev->nodename) + strlen("/event-channel") + 1];
-
- printk("close pci: backend at %s\n",dev->backend);
-
- snprintf(path, sizeof(path), "%s/state", dev->backend);
- snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
- printk("shutdown_pcifront: error changing state to %d: %s\n",
- XenbusStateClosing, err);
- goto close_pcifront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && state < XenbusStateClosing)
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
- printk("shutdown_pcifront: error changing state to %d: %s\n",
- XenbusStateClosed, err);
- goto close_pcifront;
- }
- state = xenbus_read_integer(path);
- while (state < XenbusStateClosed) {
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
- free(err);
- }
-
- if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
- printk("shutdown_pcifront: error changing state to %d: %s\n",
- XenbusStateInitialising, err);
- goto close_pcifront;
- }
- state = xenbus_read_integer(path);
- while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
- err = xenbus_wait_for_state_change(path, &state, &dev->events);
-
-close_pcifront:
- free(err);
- err2 = xenbus_unwatch_path_token(XBT_NIL, path, path);
- free(err2);
-
- snprintf(nodename, sizeof(nodename), "%s/info-ref", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
- snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
- err2 = xenbus_rm(XBT_NIL, nodename);
- free(err2);
-
- if (!err)
- free_pcifront(dev);
-}
-
-int pcifront_physical_to_virtual (struct pcifront_dev *dev,
- unsigned int *dom,
- unsigned int *bus,
- unsigned int *slot,
- unsigned int *fun)
-{
- /* FIXME: the buffer sizing is a little lazy here. 10 extra bytes
- should be enough to hold the paths we need to construct, even
- if the number of devices is large */
- char path[strlen(dev->backend) + strlen("/num_devs") + 10 + 1];
- int i, n;
- char *s, *msg = NULL;
- unsigned int dom1, bus1, slot1, fun1;
-
- if (!dev)
- dev = pcidev;
-
- snprintf(path, sizeof(path), "%s/num_devs", dev->backend);
- n = xenbus_read_integer(path);
-
- for (i = 0; i < n; i++) {
- snprintf(path, sizeof(path), "%s/dev-%d", dev->backend, i);
- msg = xenbus_read(XBT_NIL, path, &s);
- if (msg) {
- printk("Error %s when reading the PCI root name at %s\n", msg, path);
- free(msg);
- continue;
- }
-
- if (sscanf(s, "%x:%x:%x.%x", &dom1, &bus1, &slot1, &fun1) != 4) {
- printk("\"%s\" does not look like a PCI device address\n", s);
- free(s);
- continue;
- }
- free(s);
-
- if (dom1 == *dom && bus1 == *bus && slot1 == *slot && fun1 == *fun) {
- snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i);
- msg = xenbus_read(XBT_NIL, path, &s);
- if (msg) {
- printk("Error %s when reading the PCI root name at %s\n", msg, path);
- continue;
- }
-
- if (sscanf(s, "%x:%x:%x.%x", dom, bus, slot, fun) != 4) {
- printk("\"%s\" does not look like a PCI device address\n", s);
- free(s);
- continue;
- }
- free(s);
-
- return 0;
- }
- }
- return -1;
-}
-
-void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op)
-{
- if (!dev)
- dev = pcidev;
- dev->info->op = *op;
- /* Make sure info is written before the flag */
- wmb();
- set_bit(_XEN_PCIF_active, (void*) &dev->info->flags);
- notify_remote_via_evtchn(dev->evtchn);
-
- wait_event(pcifront_queue, !test_bit(_XEN_PCIF_active, (void*) &dev->info->flags));
-
- /* Make sure flag is read before info */
- rmb();
- *op = dev->info->op;
-}
-
-int pcifront_conf_read(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- unsigned int off, unsigned int size, unsigned int *val)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_conf_read;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
- op.offset = off;
- op.size = size;
-
- pcifront_op(dev, &op);
-
- if (op.err)
- return op.err;
-
- *val = op.value;
-
- return 0;
-}
-
-int pcifront_conf_write(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- unsigned int off, unsigned int size, unsigned int val)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_conf_write;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
- op.offset = off;
- op.size = size;
-
- op.value = val;
-
- pcifront_op(dev, &op);
-
- return op.err;
-}
-
-int pcifront_enable_msi(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_enable_msi;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
-
- pcifront_op(dev, &op);
-
- if (op.err)
- return op.err;
- else
- return op.value;
-}
-
-int pcifront_disable_msi(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_disable_msi;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
-
- pcifront_op(dev, &op);
-
- return op.err;
-}
-
-int pcifront_enable_msix(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun,
- struct xen_msix_entry *entries, int n)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- if (n > SH_INFO_MAX_VEC)
- return XEN_PCI_ERR_op_failed;
-
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_enable_msix;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
- op.value = n;
-
- memcpy(op.msix_entries, entries, n * sizeof(*entries));
-
- pcifront_op(dev, &op);
-
- if (op.err)
- return op.err;
-
- memcpy(entries, op.msix_entries, n * sizeof(*entries));
-
- return 0;
-}
-
-
-int pcifront_disable_msix(struct pcifront_dev *dev,
- unsigned int dom,
- unsigned int bus, unsigned int slot, unsigned int fun)
-{
- struct xen_pci_op op;
-
- if (!dev)
- dev = pcidev;
- if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
- return XEN_PCI_ERR_dev_not_found;
- memset(&op, 0, sizeof(op));
-
- op.cmd = XEN_PCI_OP_disable_msix;
- op.domain = dom;
- op.bus = bus;
- op.devfn = PCI_DEVFN(slot, fun);
-
- pcifront_op(dev, &op);
-
- return op.err;
-}
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- * File: sched.c
- * Author: Grzegorz Milos
- * Changes: Robert Kaiser
- *
- * Date: Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/time.h>
-#include <mini-os/mm.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/list.h>
-#include <mini-os/sched.h>
-#include <mini-os/semaphore.h>
-
-
-#ifdef SCHED_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-MINIOS_TAILQ_HEAD(thread_list, struct thread);
-
-struct thread *idle_thread = NULL;
-static struct thread_list exited_threads = MINIOS_TAILQ_HEAD_INITIALIZER(exited_threads);
-static struct thread_list thread_list = MINIOS_TAILQ_HEAD_INITIALIZER(thread_list);
-static int threads_started;
-
-struct thread *main_thread;
-
-void inline print_runqueue(void)
-{
- struct thread *th;
- MINIOS_TAILQ_FOREACH(th, &thread_list, thread_list)
- {
- printk(" Thread \"%s\", runnable=%d\n", th->name, is_runnable(th));
- }
- printk("\n");
-}
-
-void schedule(void)
-{
- struct thread *prev, *next, *thread, *tmp;
- unsigned long flags;
-
- if (irqs_disabled()) {
- printk("Must not call schedule() with IRQs disabled\n");
- BUG();
- }
-
- prev = current;
- local_irq_save(flags);
-
- if (in_callback) {
- printk("Must not call schedule() from a callback\n");
- BUG();
- }
-
- do {
- /* Examine all threads.
- Find a runnable thread, but also wake up expired ones and find the
- time when the next timeout expires, else use 10 seconds. */
- s_time_t now = NOW();
- s_time_t min_wakeup_time = now + SECONDS(10);
- next = NULL;
- MINIOS_TAILQ_FOREACH_SAFE(thread, &thread_list, thread_list, tmp)
- {
- if (!is_runnable(thread) && thread->wakeup_time != 0LL)
- {
- if (thread->wakeup_time <= now)
- wake(thread);
- else if (thread->wakeup_time < min_wakeup_time)
- min_wakeup_time = thread->wakeup_time;
- }
- if(is_runnable(thread))
- {
- next = thread;
- /* Put this thread on the end of the list */
- MINIOS_TAILQ_REMOVE(&thread_list, thread, thread_list);
- MINIOS_TAILQ_INSERT_TAIL(&thread_list, thread, thread_list);
- break;
- }
- }
- if (next)
- break;
- /* block until the next timeout expires, or for 10 secs, whichever comes first */
- block_domain(min_wakeup_time);
- /* handle pending events if any */
- force_evtchn_callback();
- } while(1);
- local_irq_restore(flags);
- /* Interrupting the switch is equivalent to having the next thread
- inturrupted at the return instruction. And therefore at safe point. */
- if(prev != next) switch_threads(prev, next);
-
- MINIOS_TAILQ_FOREACH_SAFE(thread, &exited_threads, thread_list, tmp)
- {
- if(thread != prev)
- {
- MINIOS_TAILQ_REMOVE(&exited_threads, thread, thread_list);
- free_pages(thread->stack, STACK_SIZE_PAGE_ORDER);
- xfree(thread);
- }
- }
-}
-
-struct thread* create_thread(char *name, void (*function)(void *), void *data)
-{
- struct thread *thread;
- unsigned long flags;
- /* Call architecture specific setup. */
- thread = arch_create_thread(name, function, data);
- /* Not runable, not exited, not sleeping */
- thread->flags = 0;
- thread->wakeup_time = 0LL;
-#ifdef HAVE_LIBC
- _REENT_INIT_PTR((&thread->reent))
-#endif
- set_runnable(thread);
- local_irq_save(flags);
- MINIOS_TAILQ_INSERT_TAIL(&thread_list, thread, thread_list);
- local_irq_restore(flags);
- return thread;
-}
-
-#ifdef HAVE_LIBC
-static struct _reent callback_reent;
-struct _reent *__getreent(void)
-{
- struct _reent *_reent;
-
- if (!threads_started)
- _reent = _impure_ptr;
- else if (in_callback)
- _reent = &callback_reent;
- else
- _reent = &get_current()->reent;
-
-#ifndef NDEBUG
-#if defined(__x86_64__) || defined(__x86__)
- {
-#ifdef __x86_64__
- register unsigned long sp asm ("rsp");
-#else
- register unsigned long sp asm ("esp");
-#endif
- if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
- static int overflowing;
- if (!overflowing) {
- overflowing = 1;
- printk("stack overflow\n");
- BUG();
- }
- }
- }
-#endif
-#else
-#error Not implemented yet
-#endif
- return _reent;
-}
-#endif
-
-void exit_thread(void)
-{
- unsigned long flags;
- struct thread *thread = current;
- printk("Thread \"%s\" exited.\n", thread->name);
- local_irq_save(flags);
- /* Remove from the thread list */
- MINIOS_TAILQ_REMOVE(&thread_list, thread, thread_list);
- clear_runnable(thread);
- /* Put onto exited list */
- MINIOS_TAILQ_INSERT_HEAD(&exited_threads, thread, thread_list);
- local_irq_restore(flags);
- /* Schedule will free the resources */
- while(1)
- {
- schedule();
- printk("schedule() returned! Trying again\n");
- }
-}
-
-void block(struct thread *thread)
-{
- thread->wakeup_time = 0LL;
- clear_runnable(thread);
-}
-
-void msleep(uint32_t millisecs)
-{
- struct thread *thread = get_current();
- thread->wakeup_time = NOW() + MILLISECS(millisecs);
- clear_runnable(thread);
- schedule();
-}
-
-void wake(struct thread *thread)
-{
- thread->wakeup_time = 0LL;
- set_runnable(thread);
-}
-
-void idle_thread_fn(void *unused)
-{
- threads_started = 1;
- while (1) {
- block(current);
- schedule();
- }
-}
-
-DECLARE_MUTEX(mutex);
-
-void th_f1(void *data)
-{
- struct timeval tv1, tv2;
-
- for(;;)
- {
- down(&mutex);
- printk("Thread \"%s\" got semaphore, runnable %d\n", current->name, is_runnable(current));
- schedule();
- printk("Thread \"%s\" releases the semaphore\n", current->name);
- up(&mutex);
-
-
- gettimeofday(&tv1, NULL);
- for(;;)
- {
- gettimeofday(&tv2, NULL);
- if(tv2.tv_sec - tv1.tv_sec > 2) break;
- }
-
-
- schedule();
- }
-}
-
-void th_f2(void *data)
-{
- for(;;)
- {
- printk("Thread OTHER executing, data 0x%lx\n", data);
- schedule();
- }
-}
-
-
-
-void init_sched(void)
-{
- printk("Initialising scheduler\n");
-
-#ifdef HAVE_LIBC
- _REENT_INIT_PTR((&callback_reent))
-#endif
- idle_thread = create_thread("Idle", idle_thread_fn, NULL);
-}
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/******************************************************************************
- * test.c
- *
- * Test code for all the various frontends; split from kernel.c
- *
- * Copyright (c) 2002-2003, K A Fraser & R Neugebauer
- * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge
- * Copyright (c) 2006, Robert Kaiser, FH Wiesbaden
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <mini-os/os.h>
-#include <mini-os/hypervisor.h>
-#include <mini-os/mm.h>
-#include <mini-os/events.h>
-#include <mini-os/time.h>
-#include <mini-os/types.h>
-#include <mini-os/lib.h>
-#include <mini-os/sched.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/netfront.h>
-#include <mini-os/blkfront.h>
-#include <mini-os/fbfront.h>
-#include <mini-os/pcifront.h>
-#include <mini-os/xmalloc.h>
-#include <fcntl.h>
-#include <xen/features.h>
-#include <xen/version.h>
-
-#ifdef CONFIG_XENBUS
-static unsigned int do_shutdown = 0;
-static unsigned int shutdown_reason;
-static DECLARE_WAIT_QUEUE_HEAD(shutdown_queue);
-#endif
-
-#ifdef CONFIG_XENBUS
-void test_xenbus(void);
-
-static void xenbus_tester(void *p)
-{
- test_xenbus();
-}
-#endif
-
-#ifndef HAVE_LIBC
-/* Should be random enough for our uses */
-int rand(void)
-{
- static unsigned int previous;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- previous += tv.tv_sec + tv.tv_usec;
- previous *= RAND_MIX;
- return previous;
-}
-#endif
-
-static void periodic_thread(void *p)
-{
- struct timeval tv;
- printk("Periodic thread started.\n");
- for(;;)
- {
- gettimeofday(&tv, NULL);
- printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec);
- msleep(1000);
- }
-}
-
-#ifdef CONFIG_NETFRONT
-static struct netfront_dev *net_dev;
-static struct semaphore net_sem = __SEMAPHORE_INITIALIZER(net_sem, 0);
-
-static void netfront_thread(void *p)
-{
- net_dev = init_netfront(NULL, NULL, NULL, NULL);
- up(&net_sem);
-}
-#endif
-
-#ifdef CONFIG_BLKFRONT
-static struct blkfront_dev *blk_dev;
-static struct blkfront_info blk_info;
-static uint64_t blk_size_read;
-static uint64_t blk_size_write;
-static struct semaphore blk_sem = __SEMAPHORE_INITIALIZER(blk_sem, 0);;
-
-struct blk_req {
- struct blkfront_aiocb aiocb;
- int rand_value;
- struct blk_req *next;
-};
-
-#ifdef BLKTEST_WRITE
-static struct blk_req *blk_to_read;
-#endif
-
-static struct blk_req *blk_alloc_req(uint64_t sector)
-{
- struct blk_req *req = xmalloc(struct blk_req);
- req->aiocb.aio_dev = blk_dev;
- req->aiocb.aio_buf = _xmalloc(blk_info.sector_size, blk_info.sector_size);
- req->aiocb.aio_nbytes = blk_info.sector_size;
- req->aiocb.aio_offset = sector * blk_info.sector_size;
- req->aiocb.data = req;
- req->next = NULL;
- return req;
-}
-
-static void blk_read_completed(struct blkfront_aiocb *aiocb, int ret)
-{
- struct blk_req *req = aiocb->data;
- if (ret)
- printk("got error code %d when reading at offset %ld\n", ret, aiocb->aio_offset);
- else
- blk_size_read += blk_info.sector_size;
- free(aiocb->aio_buf);
- free(req);
-}
-
-static void blk_read_sector(uint64_t sector)
-{
- struct blk_req *req;
-
- req = blk_alloc_req(sector);
- req->aiocb.aio_cb = blk_read_completed;
-
- blkfront_aio_read(&req->aiocb);
-}
-
-#ifdef BLKTEST_WRITE
-static void blk_write_read_completed(struct blkfront_aiocb *aiocb, int ret)
-{
- struct blk_req *req = aiocb->data;
- int rand_value;
- int i;
- int *buf;
-
- if (ret) {
- printk("got error code %d when reading back at offset %ld\n", ret, aiocb->aio_offset);
- free(aiocb->aio_buf);
- free(req);
- return;
- }
- blk_size_read += blk_info.sector_size;
- buf = (int*) aiocb->aio_buf;
- rand_value = req->rand_value;
- for (i = 0; i < blk_info.sector_size / sizeof(int); i++) {
- if (buf[i] != rand_value) {
- printk("bogus data at offset %ld\n", aiocb->aio_offset + i);
- break;
- }
- rand_value *= RAND_MIX;
- }
- free(aiocb->aio_buf);
- free(req);
-}
-
-static void blk_write_completed(struct blkfront_aiocb *aiocb, int ret)
-{
- struct blk_req *req = aiocb->data;
- if (ret) {
- printk("got error code %d when writing at offset %ld\n", ret, aiocb->aio_offset);
- free(aiocb->aio_buf);
- free(req);
- return;
- }
- blk_size_write += blk_info.sector_size;
- /* Push write check */
- req->next = blk_to_read;
- blk_to_read = req;
-}
-
-static void blk_write_sector(uint64_t sector)
-{
- struct blk_req *req;
- int rand_value;
- int i;
- int *buf;
-
- req = blk_alloc_req(sector);
- req->aiocb.aio_cb = blk_write_completed;
- req->rand_value = rand_value = rand();
-
- buf = (int*) req->aiocb.aio_buf;
- for (i = 0; i < blk_info.sector_size / sizeof(int); i++) {
- buf[i] = rand_value;
- rand_value *= RAND_MIX;
- }
-
- blkfront_aio_write(&req->aiocb);
-}
-#endif
-
-static void blkfront_thread(void *p)
-{
- time_t lasttime = 0;
-
- blk_dev = init_blkfront(NULL, &blk_info);
- if (!blk_dev) {
- up(&blk_sem);
- return;
- }
-
- if (blk_info.info & VDISK_CDROM)
- printk("Block device is a CDROM\n");
- if (blk_info.info & VDISK_REMOVABLE)
- printk("Block device is removable\n");
- if (blk_info.info & VDISK_READONLY)
- printk("Block device is read-only\n");
-
-#ifdef BLKTEST_WRITE
- if (blk_info.mode == O_RDWR) {
- blk_write_sector(0);
- blk_write_sector(blk_info.sectors-1);
- } else
-#endif
- {
- blk_read_sector(0);
- blk_read_sector(blk_info.sectors-1);
- }
-
- while (!do_shutdown) {
- uint64_t sector = rand() % blk_info.sectors;
- struct timeval tv;
-#ifdef BLKTEST_WRITE
- if (blk_info.mode == O_RDWR)
- blk_write_sector(sector);
- else
-#endif
- blk_read_sector(sector);
- blkfront_aio_poll(blk_dev);
- gettimeofday(&tv, NULL);
- if (tv.tv_sec > lasttime + 10) {
- printk("%llu read, %llu write\n", blk_size_read, blk_size_write);
- lasttime = tv.tv_sec;
- }
-
-#ifdef BLKTEST_WRITE
- while (blk_to_read) {
- struct blk_req *req = blk_to_read;
- blk_to_read = blk_to_read->next;
- req->aiocb.aio_cb = blk_write_read_completed;
- blkfront_aio_read(&req->aiocb);
- }
-#endif
- }
- up(&blk_sem);
-}
-#endif
-
-#if defined(CONFIG_FBFRONT) && defined(CONFIG_KBDFRONT)
-#define WIDTH 800
-#define HEIGHT 600
-#define DEPTH 32
-
-static uint32_t *fb;
-static int refresh_period = 50;
-static struct fbfront_dev *fb_dev;
-static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0);
-
-static void fbfront_drawvert(int x, int y1, int y2, uint32_t color)
-{
- int y;
- if (x < 0)
- return;
- if (x >= WIDTH)
- return;
- if (y1 < 0)
- y1 = 0;
- if (y2 >= HEIGHT)
- y2 = HEIGHT-1;
- for (y = y1; y <= y2; y++)
- fb[x + y*WIDTH] ^= color;
-}
-
-static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color)
-{
- int x;
- if (y < 0)
- return;
- if (y >= HEIGHT)
- return;
- if (x1 < 0)
- x1 = 0;
- if (x2 >= WIDTH)
- x2 = WIDTH-1;
- for (x = x1; x <= x2; x++)
- fb[x + y*WIDTH] ^= color;
-}
-
-static void fbfront_thread(void *p)
-{
- size_t line_length = WIDTH * (DEPTH / 8);
- size_t memsize = HEIGHT * line_length;
- unsigned long *mfns;
- int i, n = (memsize + PAGE_SIZE-1) / PAGE_SIZE;
-
- memsize = n * PAGE_SIZE;
- fb = _xmalloc(memsize, PAGE_SIZE);
- memset(fb, 0, memsize);
- mfns = xmalloc_array(unsigned long, n);
- for (i = 0; i < n; i++)
- mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE);
- fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n);
- xfree(mfns);
- if (!fb_dev) {
- xfree(fb);
- }
- up(&fbfront_sem);
-}
-
-static void clip_cursor(int *x, int *y)
-{
- if (*x < 0)
- *x = 0;
- if (*x >= WIDTH)
- *x = WIDTH - 1;
- if (*y < 0)
- *y = 0;
- if (*y >= HEIGHT)
- *y = HEIGHT - 1;
-}
-
-static void refresh_cursor(int new_x, int new_y)
-{
- static int old_x = -1, old_y = -1;
-
- if (!refresh_period)
- return;
-
- if (old_x != -1 && old_y != -1) {
- fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff);
- fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff);
- fbfront_update(fb_dev, old_x, old_y, 9, 9);
- }
- old_x = new_x;
- old_y = new_y;
- fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff);
- fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff);
- fbfront_update(fb_dev, new_x, new_y, 9, 9);
-}
-
-static struct kbdfront_dev *kbd_dev;
-static struct semaphore kbd_sem = __SEMAPHORE_INITIALIZER(kbd_sem, 0);
-static void kbdfront_thread(void *p)
-{
- DEFINE_WAIT(w);
- DEFINE_WAIT(w2);
- DEFINE_WAIT(w3);
- int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
-
- kbd_dev = init_kbdfront(NULL, 1);
- down(&fbfront_sem);
- if (!kbd_dev) {
- up(&kbd_sem);
- return;
- }
-
- refresh_cursor(x, y);
- while (1) {
- union xenkbd_in_event kbdevent;
- union xenfb_in_event fbevent;
- int sleep = 1;
-
- add_waiter(w, kbdfront_queue);
- add_waiter(w2, fbfront_queue);
- add_waiter(w3, shutdown_queue);
-
- rmb();
- if (do_shutdown)
- break;
-
- while (kbdfront_receive(kbd_dev, &kbdevent, 1) != 0) {
- sleep = 0;
- switch(kbdevent.type) {
- case XENKBD_TYPE_MOTION:
- printk("motion x:%d y:%d z:%d\n",
- kbdevent.motion.rel_x,
- kbdevent.motion.rel_y,
- kbdevent.motion.rel_z);
- x += kbdevent.motion.rel_x;
- y += kbdevent.motion.rel_y;
- z += kbdevent.motion.rel_z;
- clip_cursor(&x, &y);
- refresh_cursor(x, y);
- break;
- case XENKBD_TYPE_POS:
- printk("pos x:%d y:%d dz:%d\n",
- kbdevent.pos.abs_x,
- kbdevent.pos.abs_y,
- kbdevent.pos.rel_z);
- x = kbdevent.pos.abs_x;
- y = kbdevent.pos.abs_y;
- z = kbdevent.pos.rel_z;
- clip_cursor(&x, &y);
- refresh_cursor(x, y);
- break;
- case XENKBD_TYPE_KEY:
- printk("key %d %s\n",
- kbdevent.key.keycode,
- kbdevent.key.pressed ? "pressed" : "released");
- if (kbdevent.key.keycode == BTN_LEFT) {
- printk("mouse %s at (%d,%d,%d)\n",
- kbdevent.key.pressed ? "clic" : "release", x, y, z);
- if (kbdevent.key.pressed) {
- uint32_t color = rand();
- fbfront_drawvert(x - 16, y - 16, y + 15, color);
- fbfront_drawhoriz(x - 16, x + 15, y + 16, color);
- fbfront_drawvert(x + 16, y - 15, y + 16, color);
- fbfront_drawhoriz(x - 15, x + 16, y - 16, color);
- fbfront_update(fb_dev, x - 16, y - 16, 33, 33);
- }
- } else if (kbdevent.key.keycode == KEY_Q) {
- shutdown_reason = SHUTDOWN_poweroff;
- wmb();
- do_shutdown = 1;
- wmb();
- wake_up(&shutdown_queue);
- }
- break;
- }
- }
- while (fbfront_receive(fb_dev, &fbevent, 1) != 0) {
- sleep = 0;
- switch(fbevent.type) {
- case XENFB_TYPE_REFRESH_PERIOD:
- refresh_period = fbevent.refresh_period.period;
- printk("refresh period %d\n", refresh_period);
- refresh_cursor(x, y);
- break;
- }
- }
- if (sleep)
- schedule();
- remove_waiter(w3, shutdown_queue);
- remove_waiter(w2, fbfront_queue);
- remove_waiter(w, kbdfront_queue);
- }
- up(&kbd_sem);
-}
-#endif
-
-#ifdef CONFIG_PCIFRONT
-static struct pcifront_dev *pci_dev;
-static struct semaphore pci_sem = __SEMAPHORE_INITIALIZER(pci_sem, 0);
-
-static void print_pcidev(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun)
-{
- unsigned int vendor, device, rev, class;
-
- pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x00, 2, &vendor);
- pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x02, 2, &device);
- pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x08, 1, &rev);
- pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x0a, 2, &class);
-
- printk("%04x:%02x:%02x.%02x %04x: %04x:%04x (rev %02x)\n", domain, bus, slot, fun, class, vendor, device, rev);
-}
-
-static void pcifront_thread(void *p)
-{
- pcifront_watches(NULL);
- pci_dev = init_pcifront(NULL);
- if (!pci_dev) {
- up(&pci_sem);
- return;
- }
- printk("PCI devices:\n");
- pcifront_scan(pci_dev, print_pcidev);
- up(&pci_sem);
-}
-#endif
-
-void shutdown_frontends(void)
-{
-#ifdef CONFIG_NETFRONT
- down(&net_sem);
- if (net_dev)
- shutdown_netfront(net_dev);
-#endif
-
-#ifdef CONFIG_BLKFRONT
- down(&blk_sem);
- if (blk_dev)
- shutdown_blkfront(blk_dev);
-#endif
-
-#if defined(CONFIG_FBFRONT) && defined(CONFIG_KBDFRONT)
- if (fb_dev)
- shutdown_fbfront(fb_dev);
-
- down(&kbd_sem);
- if (kbd_dev)
- shutdown_kbdfront(kbd_dev);
-#endif
-
-#ifdef CONFIG_PCIFRONT
- down(&pci_sem);
- if (pci_dev)
- shutdown_pcifront(pci_dev);
-#endif
-}
-
-#ifdef CONFIG_XENBUS
-void app_shutdown(unsigned reason)
-{
- shutdown_reason = reason;
- wmb();
- do_shutdown = 1;
- wmb();
- wake_up(&shutdown_queue);
-}
-
-static void shutdown_thread(void *p)
-{
- DEFINE_WAIT(w);
-
- while (1) {
- add_waiter(w, shutdown_queue);
- rmb();
- if (do_shutdown) {
- rmb();
- break;
- }
- schedule();
- remove_waiter(w, shutdown_queue);
- }
-
- shutdown_frontends();
-
- HYPERVISOR_shutdown(shutdown_reason);
-}
-#endif
-
-int app_main(start_info_t *si)
-{
- printk("Test main: start_info=%p\n", si);
-#ifdef CONFIG_XENBUS
- create_thread("xenbus_tester", xenbus_tester, si);
-#endif
- create_thread("periodic_thread", periodic_thread, si);
-#ifdef CONFIG_NETFRONT
- create_thread("netfront", netfront_thread, si);
-#endif
-#ifdef CONFIG_BLKFRONT
- create_thread("blkfront", blkfront_thread, si);
-#endif
-#if defined(CONFIG_FBFRONT) && defined(CONFIG_KBDFRONT)
- create_thread("fbfront", fbfront_thread, si);
- create_thread("kbdfront", kbdfront_thread, si);
-#endif
-#ifdef CONFIG_PCIFRONT
- create_thread("pcifront", pcifront_thread, si);
-#endif
-#ifdef CONFIG_XENBUS
- create_thread("shutdown", shutdown_thread, si);
-#endif
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/char/tpm.c
- * from the linux kernel
- *
- * Copyright (C) 2004 IBM Corporation
- *
- * This code has also been derived from drivers/char/tpm/tpm_tis.c
- * from the linux kernel
- *
- * Copyright (C) 2005, 2006 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, version 2
- * of the License
- */
-#include <mini-os/ioremap.h>
-#include <mini-os/iorw.h>
-#include <mini-os/tpm_tis.h>
-#include <mini-os/os.h>
-#include <mini-os/sched.h>
-#include <mini-os/byteorder.h>
-#include <mini-os/events.h>
-#include <mini-os/wait.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/lib.h>
-#include <errno.h>
-#include <stdbool.h>
-
-#ifndef min
- #define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
-#endif
-#define ADJUST_TIMEOUTS_TO_STANDARD(initial,standard,timeout_no) \
- if((initial) < (standard)){ \
- (initial) = (standard); \
- printk("Timeout %c was adjusted to standard value.\n",timeout_no); \
- }
-
-#define TPM_HEADER_SIZE 10
-
-#define TPM_BUFSIZE 2048
-
-struct tpm_input_header {
- uint16_t tag;
- uint32_t length;
- uint32_t ordinal;
-}__attribute__((packed));
-
-struct tpm_output_header {
- uint16_t tag;
- uint32_t length;
- uint32_t return_code;
-}__attribute__((packed));
-
-struct stclear_flags_t {
- uint16_t tag;
- uint8_t deactivated;
- uint8_t disableForceClear;
- uint8_t physicalPresence;
- uint8_t physicalPresenceLock;
- uint8_t bGlobalLock;
-}__attribute__((packed));
-
-struct tpm_version_t {
- uint8_t Major;
- uint8_t Minor;
- uint8_t revMajor;
- uint8_t revMinor;
-}__attribute__((packed));
-
-struct tpm_version_1_2_t {
- uint16_t tag;
- uint8_t Major;
- uint8_t Minor;
- uint8_t revMajor;
- uint8_t revMinor;
-}__attribute__((packed));
-
-struct timeout_t {
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
-}__attribute__((packed));
-
-struct duration_t {
- uint32_t tpm_short;
- uint32_t tpm_medium;
- uint32_t tpm_long;
-}__attribute__((packed));
-
-struct permanent_flags_t {
- uint16_t tag;
- uint8_t disable;
- uint8_t ownership;
- uint8_t deactivated;
- uint8_t readPubek;
- uint8_t disableOwnerClear;
- uint8_t allowMaintenance;
- uint8_t physicalPresenceLifetimeLock;
- uint8_t physicalPresenceHWEnable;
- uint8_t physicalPresenceCMDEnable;
- uint8_t CEKPUsed;
- uint8_t TPMpost;
- uint8_t TPMpostLock;
- uint8_t FIPS;
- uint8_t operator;
- uint8_t enableRevokeEK;
- uint8_t nvLocked;
- uint8_t readSRKPub;
- uint8_t tpmEstablished;
- uint8_t maintenanceDone;
- uint8_t disableFullDALogicInfo;
-}__attribute__((packed));
-
-typedef union {
- struct permanent_flags_t perm_flags;
- struct stclear_flags_t stclear_flags;
- bool owned;
- uint32_t num_pcrs;
- struct tpm_version_t tpm_version;
- struct tpm_version_1_2_t tpm_version_1_2;
- uint32_t manufacturer_id;
- struct timeout_t timeout;
- struct duration_t duration;
-} cap_t;
-
-struct tpm_getcap_params_in {
- uint32_t cap;
- uint32_t subcap_size;
- uint32_t subcap;
-}__attribute__((packed));
-
-struct tpm_getcap_params_out {
- uint32_t cap_size;
- cap_t cap;
-}__attribute__((packed));
-
-struct tpm_readpubek_params_out {
- uint8_t algorithm[4];
- uint8_t encscheme[2];
- uint8_t sigscheme[2];
- uint32_t paramsize;
- uint8_t parameters[12]; /*assuming RSA*/
- uint32_t keysize;
- uint8_t modulus[256];
- uint8_t checksum[20];
-}__attribute__((packed));
-
-typedef union {
- struct tpm_input_header in;
- struct tpm_output_header out;
-} tpm_cmd_header;
-
-#define TPM_DIGEST_SIZE 20
-struct tpm_pcrread_out {
- uint8_t pcr_result[TPM_DIGEST_SIZE];
-}__attribute__((packed));
-
-struct tpm_pcrread_in {
- uint32_t pcr_idx;
-}__attribute__((packed));
-
-struct tpm_pcrextend_in {
- uint32_t pcr_idx;
- uint8_t hash[TPM_DIGEST_SIZE];
-}__attribute__((packed));
-
-typedef union {
- struct tpm_getcap_params_out getcap_out;
- struct tpm_readpubek_params_out readpubek_out;
- uint8_t readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
- struct tpm_getcap_params_in getcap_in;
- struct tpm_pcrread_in pcrread_in;
- struct tpm_pcrread_out pcrread_out;
- struct tpm_pcrextend_in pcrextend_in;
-} tpm_cmd_params;
-
-struct tpm_cmd_t {
- tpm_cmd_header header;
- tpm_cmd_params params;
-}__attribute__((packed));
-
-
-enum tpm_duration {
- TPM_SHORT = 0,
- TPM_MEDIUM = 1,
- TPM_LONG = 2,
- TPM_UNDEFINED,
-};
-
-#define TPM_MAX_ORDINAL 243
-#define TPM_MAX_PROTECTED_ORDINAL 12
-#define TPM_PROTECTED_ORDINAL_MASK 0xFF
-
-extern const uint8_t tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL];
-extern const uint8_t tpm_ordinal_duration[TPM_MAX_ORDINAL];
-
-#define TPM_DIGEST_SIZE 20
-#define TPM_ERROR_SIZE 10
-#define TPM_RET_CODE_IDX 6
-
-/* tpm_capabilities */
-#define TPM_CAP_FLAG cpu_to_be32(4)
-#define TPM_CAP_PROP cpu_to_be32(5)
-#define CAP_VERSION_1_1 cpu_to_be32(0x06)
-#define CAP_VERSION_1_2 cpu_to_be32(0x1A)
-
-/* tpm_sub_capabilities */
-#define TPM_CAP_PROP_PCR cpu_to_be32(0x101)
-#define TPM_CAP_PROP_MANUFACTURER cpu_to_be32(0x103)
-#define TPM_CAP_FLAG_PERM cpu_to_be32(0x108)
-#define TPM_CAP_FLAG_VOL cpu_to_be32(0x109)
-#define TPM_CAP_PROP_OWNER cpu_to_be32(0x111)
-#define TPM_CAP_PROP_TIS_TIMEOUT cpu_to_be32(0x115)
-#define TPM_CAP_PROP_TIS_DURATION cpu_to_be32(0x120)
-
-
-#define TPM_INTERNAL_RESULT_SIZE 200
-#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
-#define TPM_ORD_GET_CAP cpu_to_be32(101)
-
-extern const struct tpm_input_header tpm_getcap_header;
-
-
-
-const uint8_t tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
- TPM_UNDEFINED, /* 0 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 5 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 10 */
- TPM_SHORT,
-};
-
-const uint8_t tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
- TPM_UNDEFINED, /* 0 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 5 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 10 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_LONG,
- TPM_MEDIUM, /* 15 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT, /* 20 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT, /* 25 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 30 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 35 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 40 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 45 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_LONG,
- TPM_MEDIUM, /* 50 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 55 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 60 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 65 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 70 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 75 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 80 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT,
- TPM_UNDEFINED, /* 85 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 90 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 95 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 100 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 105 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 110 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 115 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 120 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 125 */
- TPM_SHORT,
- TPM_LONG,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 130 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 135 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 140 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 145 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 150 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 155 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 160 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 165 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 170 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 175 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 180 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM, /* 185 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 190 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 195 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 200 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 205 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 210 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 215 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 220 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 225 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 230 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 235 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 240 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
-};
-
-const struct tpm_input_header tpm_getcap_header = {
- .tag = TPM_TAG_RQU_COMMAND,
- .length = cpu_to_be32(22),
- .ordinal = TPM_ORD_GET_CAP
-};
-
-
-enum tis_access {
- TPM_ACCESS_VALID = 0x80,
- TPM_ACCESS_ACTIVE_LOCALITY = 0x20, /* (R) */
- TPM_ACCESS_RELINQUISH_LOCALITY = 0x20,/* (W) */
- TPM_ACCESS_REQUEST_PENDING = 0x04, /* (W) */
- TPM_ACCESS_REQUEST_USE = 0x02, /* (W) */
-};
-
-enum tis_status {
- TPM_STS_VALID = 0x80, /* (R) */
- TPM_STS_COMMAND_READY = 0x40, /* (R) */
- TPM_STS_DATA_AVAIL = 0x10, /* (R) */
- TPM_STS_DATA_EXPECT = 0x08, /* (R) */
- TPM_STS_GO = 0x20, /* (W) */
-};
-
-enum tis_int_flags {
- TPM_GLOBAL_INT_ENABLE = 0x80000000,
- TPM_INTF_BURST_COUNT_STATIC = 0x100,
- TPM_INTF_CMD_READY_INT = 0x080,
- TPM_INTF_INT_EDGE_FALLING = 0x040,
- TPM_INTF_INT_EDGE_RISING = 0x020,
- TPM_INTF_INT_LEVEL_LOW = 0x010,
- TPM_INTF_INT_LEVEL_HIGH = 0x008,
- TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
- TPM_INTF_STS_VALID_INT = 0x002,
- TPM_INTF_DATA_AVAIL_INT = 0x001,
-};
-
-enum tis_defaults {
- TIS_MEM_BASE = 0xFED40000,
- TIS_MEM_LEN = 0x5000,
- TIS_SHORT_TIMEOUT = 750, /*ms*/
- TIS_LONG_TIMEOUT = 2000, /*2 sec */
-};
-
-#define TPM_TIMEOUT 5
-
-#define TPM_ACCESS(t, l) (((uint8_t*)t->pages[l]) + 0x0000)
-#define TPM_INT_ENABLE(t, l) ((uint32_t*)(((uint8_t*)t->pages[l]) + 0x0008))
-#define TPM_INT_VECTOR(t, l) (((uint8_t*)t->pages[l]) + 0x000C)
-#define TPM_INT_STATUS(t, l) (((uint8_t*)t->pages[l]) + 0x0010)
-#define TPM_INTF_CAPS(t, l) ((uint32_t*)(((uint8_t*)t->pages[l]) + 0x0014))
-#define TPM_STS(t, l) ((uint8_t*)(((uint8_t*)t->pages[l]) + 0x0018))
-#define TPM_DATA_FIFO(t, l) (((uint8_t*)t->pages[l]) + 0x0024)
-
-#define TPM_DID_VID(t, l) ((uint32_t*)(((uint8_t*)t->pages[l]) + 0x0F00))
-#define TPM_RID(t, l) (((uint8_t*)t->pages[l]) + 0x0F04)
-
-struct tpm_chip {
- int enabled_localities;
- int locality;
- unsigned long baseaddr;
- uint8_t* pages[5];
- int did, vid, rid;
-
- uint8_t data_buffer[TPM_BUFSIZE];
- int data_len;
-
- s_time_t timeout_a, timeout_b, timeout_c, timeout_d;
- s_time_t duration[3];
-
-#ifdef HAVE_LIBC
- int fd;
-#endif
-
- unsigned int irq;
- struct wait_queue_head read_queue;
- struct wait_queue_head int_queue;
-};
-
-
-static void __init_tpm_chip(struct tpm_chip* tpm) {
- tpm->enabled_localities = TPM_TIS_EN_LOCLALL;
- tpm->locality = -1;
- tpm->baseaddr = 0;
- tpm->pages[0] = tpm->pages[1] = tpm->pages[2] = tpm->pages[3] = tpm->pages[4] = NULL;
- tpm->vid = 0;
- tpm->did = 0;
- tpm->irq = 0;
- init_waitqueue_head(&tpm->read_queue);
- init_waitqueue_head(&tpm->int_queue);
-
- tpm->data_len = -1;
-
-#ifdef HAVE_LIBC
- tpm->fd = -1;
-#endif
-}
-
-/*
- * Returns max number of nsecs to wait
- */
-s_time_t tpm_calc_ordinal_duration(struct tpm_chip *chip,
- uint32_t ordinal)
-{
- int duration_idx = TPM_UNDEFINED;
- s_time_t duration = 0;
-
- if (ordinal < TPM_MAX_ORDINAL)
- duration_idx = tpm_ordinal_duration[ordinal];
- else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
- TPM_MAX_PROTECTED_ORDINAL)
- duration_idx =
- tpm_protected_ordinal_duration[ordinal &
- TPM_PROTECTED_ORDINAL_MASK];
-
- if (duration_idx != TPM_UNDEFINED) {
- duration = chip->duration[duration_idx];
- }
-
- if (duration <= 0) {
- return SECONDS(120);
- }
- else
- {
- return duration;
- }
-}
-
-
-static int locality_enabled(struct tpm_chip* tpm, int l) {
- return l >= 0 && tpm->enabled_localities & (1 << l);
-}
-
-static int check_locality(struct tpm_chip* tpm, int l) {
- if(locality_enabled(tpm, l) && (ioread8(TPM_ACCESS(tpm, l)) &
- (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
- return l;
- }
- return -1;
-}
-
-void release_locality(struct tpm_chip* tpm, int l, int force)
-{
- if (locality_enabled(tpm, l) && (force || (ioread8(TPM_ACCESS(tpm, l)) &
- (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))) {
- iowrite8(TPM_ACCESS(tpm, l), TPM_ACCESS_RELINQUISH_LOCALITY);
- }
-}
-
-int tpm_tis_request_locality(struct tpm_chip* tpm, int l) {
-
- s_time_t stop;
- /*Make sure locality is valid */
- if(!locality_enabled(tpm, l)) {
- printk("tpm_tis_change_locality() Tried to change to locality %d, but it is disabled or invalid!\n", l);
- return -1;
- }
- /* Check if we already have the current locality */
- if(check_locality(tpm, l) >= 0) {
- return tpm->locality = l;
- }
- /* Set the new locality*/
- iowrite8(TPM_ACCESS(tpm, l), TPM_ACCESS_REQUEST_USE);
-
- if(tpm->irq) {
- /* Wait for interrupt */
- wait_event_deadline(tpm->int_queue, (check_locality(tpm, l) >= 0), NOW() + tpm->timeout_a);
-
- /* FIXME: Handle timeout event, should return error in that case */
- return l;
- } else {
- /* Wait for burstcount */
- stop = NOW() + tpm->timeout_a;
- do {
- if(check_locality(tpm, l) >= 0) {
- return tpm->locality = l;
- }
- msleep(TPM_TIMEOUT);
- } while(NOW() < stop);
- }
-
- printk("REQ LOCALITY FAILURE\n");
- return -1;
-}
-
-static uint8_t tpm_tis_status(struct tpm_chip* tpm) {
- return ioread8(TPM_STS(tpm, tpm->locality));
-}
-
-/* This causes the current command to be aborted */
-static void tpm_tis_ready(struct tpm_chip* tpm) {
- iowrite8(TPM_STS(tpm, tpm->locality), TPM_STS_COMMAND_READY);
-}
-#define tpm_tis_cancel_cmd(v) tpm_tis_ready(v)
-
-static int get_burstcount(struct tpm_chip* tpm) {
- s_time_t stop;
- int burstcnt;
-
- stop = NOW() + tpm->timeout_d;
- do {
- burstcnt = ioread8((TPM_STS(tpm, tpm->locality) + 1));
- burstcnt += ioread8(TPM_STS(tpm, tpm->locality) + 2) << 8;
-
- if (burstcnt) {
- return burstcnt;
- }
- msleep(TPM_TIMEOUT);
- } while(NOW() < stop);
- return -EBUSY;
-}
-
-static int wait_for_stat(struct tpm_chip* tpm, uint8_t mask,
- unsigned long timeout, struct wait_queue_head* queue) {
- s_time_t stop;
- uint8_t status;
-
- status = tpm_tis_status(tpm);
- if((status & mask) == mask) {
- return 0;
- }
-
- if(tpm->irq) {
- wait_event_deadline(*queue, ((tpm_tis_status(tpm) & mask) == mask), timeout);
- /* FIXME: Check for timeout and return -ETIME */
- return 0;
- } else {
- stop = NOW() + timeout;
- do {
- msleep(TPM_TIMEOUT);
- status = tpm_tis_status(tpm);
- if((status & mask) == mask)
- return 0;
- } while( NOW() < stop);
- }
- return -ETIME;
-}
-
-static int recv_data(struct tpm_chip* tpm, uint8_t* buf, size_t count) {
- int size = 0;
- int burstcnt;
- while( size < count &&
- wait_for_stat(tpm,
- TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- tpm->timeout_c,
- &tpm->read_queue)
- == 0) {
- burstcnt = get_burstcount(tpm);
- for(; burstcnt > 0 && size < count; --burstcnt)
- {
- buf[size++] = ioread8(TPM_DATA_FIFO(tpm, tpm->locality));
- }
- }
- return size;
-}
-
-int tpm_tis_recv(struct tpm_chip* tpm, uint8_t* buf, size_t count) {
- int size = 0;
- int expected, status;
-
- if (count < TPM_HEADER_SIZE) {
- size = -EIO;
- goto out;
- }
-
- /* read first 10 bytes, including tag, paramsize, and result */
- if((size =
- recv_data(tpm, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
- printk("Error reading tpm cmd header\n");
- goto out;
- }
-
- expected = be32_to_cpu(*((uint32_t*)(buf + 2)));
- if(expected > count) {
- size = -EIO;
- goto out;
- }
-
- if((size += recv_data(tpm, & buf[TPM_HEADER_SIZE],
- expected - TPM_HEADER_SIZE)) < expected) {
- printk("Unable to read rest of tpm command size=%d expected=%d\n", size, expected);
- size = -ETIME;
- goto out;
- }
-
- wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c, &tpm->int_queue);
- status = tpm_tis_status(tpm);
- if(status & TPM_STS_DATA_AVAIL) {
- printk("Error: left over data\n");
- size = -EIO;
- goto out;
- }
-
-out:
- tpm_tis_ready(tpm);
- release_locality(tpm, tpm->locality, 0);
- return size;
-}
-int tpm_tis_send(struct tpm_chip* tpm, uint8_t* buf, size_t len) {
- int rc;
- int status, burstcnt = 0;
- int count = 0;
- uint32_t ordinal;
-
- if(tpm_tis_request_locality(tpm, tpm->locality) < 0) {
- return -EBUSY;
- }
-
- status = tpm_tis_status(tpm);
- if((status & TPM_STS_COMMAND_READY) == 0) {
- tpm_tis_ready(tpm);
- if(wait_for_stat(tpm, TPM_STS_COMMAND_READY, tpm->timeout_b, &tpm->int_queue) < 0) {
- rc = -ETIME;
- goto out_err;
- }
- }
-
- while(count < len - 1) {
- burstcnt = get_burstcount(tpm);
- for(;burstcnt > 0 && count < len -1; --burstcnt) {
- iowrite8(TPM_DATA_FIFO(tpm, tpm->locality), buf[count++]);
- }
-
- wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c, &tpm->int_queue);
- status = tpm_tis_status(tpm);
- if((status & TPM_STS_DATA_EXPECT) == 0) {
- rc = -EIO;
- goto out_err;
- }
- }
-
- /*Write last byte*/
- iowrite8(TPM_DATA_FIFO(tpm, tpm->locality), buf[count]);
- wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c, &tpm->read_queue);
- status = tpm_tis_status(tpm);
- if((status & TPM_STS_DATA_EXPECT) != 0) {
- rc = -EIO;
- goto out_err;
- }
-
- /*go and do it*/
- iowrite8(TPM_STS(tpm, tpm->locality), TPM_STS_GO);
-
- if(tpm->irq) {
- /*Wait for interrupt */
- ordinal = be32_to_cpu(*(buf + 6));
- if(wait_for_stat(tpm,
- TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- tpm_calc_ordinal_duration(tpm, ordinal),
- &tpm->read_queue) < 0) {
- rc = -ETIME;
- goto out_err;
- }
- }
-#ifdef HAVE_LIBC
- if(tpm->fd >= 0) {
- files[tpm->fd].read = 0;
- files[tpm->fd].tpm_tis.respgot = 0;
- files[tpm->fd].tpm_tis.offset = 0;
- }
-#endif
- return len;
-
-out_err:
- tpm_tis_ready(tpm);
- release_locality(tpm, tpm->locality, 0);
- return rc;
-}
-
-static void tpm_tis_irq_handler(evtchn_port_t port, struct pt_regs *regs, void* data)
-{
- struct tpm_chip* tpm = data;
- uint32_t interrupt;
- int i;
-
- interrupt = ioread32(TPM_INT_STATUS(tpm, tpm->locality));
- if(interrupt == 0) {
- return;
- }
-
- if(interrupt & TPM_INTF_DATA_AVAIL_INT) {
- wake_up(&tpm->read_queue);
- }
- if(interrupt & TPM_INTF_LOCALITY_CHANGE_INT) {
- for(i = 0; i < 5; ++i) {
- if(check_locality(tpm, i) >= 0) {
- break;
- }
- }
- }
- if(interrupt & (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
- TPM_INTF_CMD_READY_INT)) {
- wake_up(&tpm->int_queue);
- }
-
- /* Clear interrupts handled with TPM_EOI */
- iowrite32(TPM_INT_STATUS(tpm, tpm->locality), interrupt);
- ioread32(TPM_INT_STATUS(tpm, tpm->locality));
- return;
-}
-
-/*
- * Internal kernel interface to transmit TPM commands
- */
-static ssize_t tpm_transmit(struct tpm_chip *chip, const uint8_t *buf,
- size_t bufsiz)
-{
- ssize_t rc;
- uint32_t count, ordinal;
- s_time_t stop;
-
- count = be32_to_cpu(*((uint32_t *) (buf + 2)));
- ordinal = be32_to_cpu(*((uint32_t *) (buf + 6)));
- if (count == 0)
- return -ENODATA;
- if (count > bufsiz) {
- printk("Error: invalid count value %x %zx \n", count, bufsiz);
- return -E2BIG;
- }
-
- //down(&chip->tpm_mutex);
-
- if ((rc = tpm_tis_send(chip, (uint8_t *) buf, count)) < 0) {
- printk("tpm_transmit: tpm_send: error %ld\n", rc);
- goto out;
- }
-
- if (chip->irq)
- goto out_recv;
-
- stop = NOW() + tpm_calc_ordinal_duration(chip, ordinal);
- do {
- uint8_t status = tpm_tis_status(chip);
- if ((status & (TPM_STS_DATA_AVAIL | TPM_STS_VALID)) ==
- (TPM_STS_DATA_AVAIL | TPM_STS_VALID))
- goto out_recv;
-
- if ((status == TPM_STS_COMMAND_READY)) {
- printk("TPM Error: Operation Canceled\n");
- rc = -ECANCELED;
- goto out;
- }
-
- msleep(TPM_TIMEOUT); /* CHECK */
- rmb();
- } while (NOW() < stop);
-
- /* Cancel the command */
- tpm_tis_cancel_cmd(chip);
- printk("TPM Operation Timed out\n");
- rc = -ETIME;
- goto out;
-
-out_recv:
- if((rc = tpm_tis_recv(chip, (uint8_t *) buf, bufsiz)) < 0) {
- printk("tpm_transmit: tpm_recv: error %d\n", rc);
- }
-out:
- //up(&chip->tpm_mutex);
- return rc;
-}
-
-static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
- int len, const char *desc)
-{
- int err;
-
- len = tpm_transmit(chip,(uint8_t *) cmd, len);
- if (len < 0)
- return len;
- if (len == TPM_ERROR_SIZE) {
- err = be32_to_cpu(cmd->header.out.return_code);
- printk("A TPM error (%d) occurred %s\n", err, desc);
- return err;
- }
- return 0;
-}
-
-int tpm_get_timeouts(struct tpm_chip *chip)
-{
- struct tpm_cmd_t tpm_cmd;
- struct timeout_t *timeout_cap;
- struct duration_t *duration_cap;
- ssize_t rc;
- uint32_t timeout;
- unsigned int scale = 1;
-
- tpm_cmd.header.in = tpm_getcap_header;
- tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
- tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
- tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
-
- if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the timeouts")) != 0) {
- printk("transmit failed %d\n", rc);
- goto duration;
- }
-
- if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
- be32_to_cpu(tpm_cmd.header.out.length) !=
- sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 4 * sizeof(uint32_t)) {
- return -EINVAL;
- }
-
- timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
- /* Don't overwrite default if value is 0 */
- timeout = be32_to_cpu(timeout_cap->a);
- if(timeout && timeout < 1000) {
- /* timeouts in msc rather usec */
- scale = 1000;
- }
- if (timeout)
- chip->timeout_a = MICROSECS(timeout * scale); /*Convert to msec */
- ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_a,MILLISECS(TIS_SHORT_TIMEOUT),'a');
-
- timeout = be32_to_cpu(timeout_cap->b);
- if (timeout)
- chip->timeout_b = MICROSECS(timeout * scale); /*Convert to msec */
- ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_b,MILLISECS(TIS_LONG_TIMEOUT),'b');
-
- timeout = be32_to_cpu(timeout_cap->c);
- if (timeout)
- chip->timeout_c = MICROSECS(timeout * scale); /*Convert to msec */
- ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_c,MILLISECS(TIS_SHORT_TIMEOUT),'c');
-
- timeout = be32_to_cpu(timeout_cap->d);
- if (timeout)
- chip->timeout_d = MICROSECS(timeout * scale); /*Convert to msec */
- ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_d,MILLISECS(TIS_SHORT_TIMEOUT),'d');
-
-duration:
- tpm_cmd.header.in = tpm_getcap_header;
- tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
- tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
- tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
-
- if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the durations")) < 0) {
- return rc;
- }
-
- if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
- be32_to_cpu(tpm_cmd.header.out.length) !=
- sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 3 * sizeof(uint32_t)) {
- return -EINVAL;
- }
-
- duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
- chip->duration[TPM_SHORT] = MICROSECS(be32_to_cpu(duration_cap->tpm_short));
- chip->duration[TPM_MEDIUM] = MICROSECS(be32_to_cpu(duration_cap->tpm_medium));
- chip->duration[TPM_LONG] = MICROSECS(be32_to_cpu(duration_cap->tpm_long));
-
- /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
- * value wrong and apparently reports msecs rather than usecs. So we
- * fix up the resulting too-small TPM_SHORT value to make things work.
- */
- if (chip->duration[TPM_SHORT] < MILLISECS(10)) {
- chip->duration[TPM_SHORT] = SECONDS(1);
- chip->duration[TPM_MEDIUM] *= 1000;
- chip->duration[TPM_LONG] *= 1000;
- printk("Adjusting TPM timeout parameters\n");
- }
-
- return 0;
-}
-
-
-
-void tpm_continue_selftest(struct tpm_chip* chip) {
- uint8_t data[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 10, /* length */
- 0, 0, 0, 83, /* TPM_ORD_GetCapability */
- };
-
- tpm_transmit(chip, data, sizeof(data));
-}
-
-ssize_t tpm_getcap(struct tpm_chip *chip, uint32_t subcap_id, cap_t *cap,
- const char *desc)
-{
- struct tpm_cmd_t tpm_cmd;
- int rc;
-
- tpm_cmd.header.in = tpm_getcap_header;
- if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
- tpm_cmd.params.getcap_in.cap = subcap_id;
- /*subcap field not necessary */
- tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
- tpm_cmd.header.in.length -= cpu_to_be32(sizeof(uint32_t));
- } else {
- if (subcap_id == TPM_CAP_FLAG_PERM ||
- subcap_id == TPM_CAP_FLAG_VOL)
- tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
- else
- tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
- tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
- tpm_cmd.params.getcap_in.subcap = subcap_id;
- }
- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
- if (!rc)
- *cap = tpm_cmd.params.getcap_out.cap;
- return rc;
-}
-
-
-struct tpm_chip* init_tpm_tis(unsigned long baseaddr, int localities, unsigned int irq)
-{
- int i;
- unsigned long addr;
- struct tpm_chip* tpm = NULL;
- uint32_t didvid;
- uint32_t intfcaps;
- uint32_t intmask;
-
- printk("============= Init TPM TIS Driver ==============\n");
-
- /*Sanity check the localities input */
- if(localities & ~TPM_TIS_EN_LOCLALL) {
- printk("init_tpm_tis() Invalid locality specification! %X\n", localities);
- goto abort_egress;
- }
-
- printk("IOMEM Machine Base Address: %lX\n", baseaddr);
-
- /* Create the tpm data structure */
- tpm = malloc(sizeof(struct tpm_chip));
- __init_tpm_chip(tpm);
-
- /* Set the enabled localities - if 0 we leave default as all enabled */
- if(localities != 0) {
- tpm->enabled_localities = localities;
- }
- printk("Enabled Localities: ");
- for(i = 0; i < 5; ++i) {
- if(locality_enabled(tpm, i)) {
- printk("%d ", i);
- }
- }
- printk("\n");
-
- /* Set the base machine address */
- tpm->baseaddr = baseaddr;
-
- /* Set default timeouts */
- tpm->timeout_a = MILLISECS(TIS_SHORT_TIMEOUT);
- tpm->timeout_b = MILLISECS(TIS_LONG_TIMEOUT);
- tpm->timeout_c = MILLISECS(TIS_SHORT_TIMEOUT);
- tpm->timeout_d = MILLISECS(TIS_SHORT_TIMEOUT);
-
- /*Map the mmio pages */
- addr = tpm->baseaddr;
- for(i = 0; i < 5; ++i) {
- if(locality_enabled(tpm, i)) {
- /* Map the page in now */
- if((tpm->pages[i] = ioremap_nocache(addr, PAGE_SIZE)) == NULL) {
- printk("Unable to map iomem page a address %p\n", addr);
- goto abort_egress;
- }
-
- /* Set default locality to the first enabled one */
- if (tpm->locality < 0) {
- if(tpm_tis_request_locality(tpm, i) < 0) {
- printk("Unable to request locality %d??\n", i);
- goto abort_egress;
- }
- }
- }
- addr += PAGE_SIZE;
- }
-
-
- /* Get the vendor and device ids */
- didvid = ioread32(TPM_DID_VID(tpm, tpm->locality));
- tpm->did = didvid >> 16;
- tpm->vid = didvid & 0xFFFF;
-
-
- /* Get the revision id */
- tpm->rid = ioread8(TPM_RID(tpm, tpm->locality));
-
- printk("1.2 TPM (device-id=0x%X vendor-id = %X rev-id = %X)\n", tpm->did, tpm->vid, tpm->rid);
-
- intfcaps = ioread32(TPM_INTF_CAPS(tpm, tpm->locality));
- printk("TPM interface capabilities (0x%x):\n", intfcaps);
- if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
- printk("\tBurst Count Static\n");
- if (intfcaps & TPM_INTF_CMD_READY_INT)
- printk("\tCommand Ready Int Support\n");
- if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
- printk("\tInterrupt Edge Falling\n");
- if (intfcaps & TPM_INTF_INT_EDGE_RISING)
- printk("\tInterrupt Edge Rising\n");
- if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
- printk("\tInterrupt Level Low\n");
- if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
- printk("\tInterrupt Level High\n");
- if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
- printk("\tLocality Change Int Support\n");
- if (intfcaps & TPM_INTF_STS_VALID_INT)
- printk("\tSts Valid Int Support\n");
- if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
- printk("\tData Avail Int Support\n");
-
- /*Interupt setup */
- intmask = ioread32(TPM_INT_ENABLE(tpm, tpm->locality));
-
- intmask |= TPM_INTF_CMD_READY_INT
- | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
- | TPM_INTF_STS_VALID_INT;
-
- iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask);
-
- /*If interupts are enabled, handle it */
- if(irq) {
- if(irq != TPM_PROBE_IRQ) {
- tpm->irq = irq;
- } else {
- /*FIXME add irq probing feature later */
- printk("IRQ probing not implemented\n");
- }
- }
-
- if(tpm->irq) {
- iowrite8(TPM_INT_VECTOR(tpm, tpm->locality), tpm->irq);
-
- if(bind_pirq(tpm->irq, 1, tpm_tis_irq_handler, tpm) != 0) {
- printk("Unabled to request irq: %u for use\n", tpm->irq);
- printk("Will use polling mode\n");
- tpm->irq = 0;
- } else {
- /* Clear all existing */
- iowrite32(TPM_INT_STATUS(tpm, tpm->locality), ioread32(TPM_INT_STATUS(tpm, tpm->locality)));
-
- /* Turn on interrupts */
- iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask | TPM_GLOBAL_INT_ENABLE);
- }
- }
-
- if(tpm_get_timeouts(tpm)) {
- printk("Could not get TPM timeouts and durations\n");
- goto abort_egress;
- }
- tpm_continue_selftest(tpm);
-
-
- return tpm;
-abort_egress:
- if(tpm != NULL) {
- shutdown_tpm_tis(tpm);
- }
- return NULL;
-}
-
-void shutdown_tpm_tis(struct tpm_chip* tpm){
- int i;
-
- printk("Shutting down tpm_tis device\n");
-
- iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), ~TPM_GLOBAL_INT_ENABLE);
-
- /*Unmap all of the mmio pages */
- for(i = 0; i < 5; ++i) {
- if(tpm->pages[i] != NULL) {
- iounmap(tpm->pages[i], PAGE_SIZE);
- tpm->pages[i] = NULL;
- }
- }
- free(tpm);
- return;
-}
-
-
-int tpm_tis_cmd(struct tpm_chip* tpm, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen)
-{
- if(tpm->locality < 0) {
- printk("tpm_tis_cmd() failed! locality not set!\n");
- return -1;
- }
- if(reqlen > TPM_BUFSIZE) {
- reqlen = TPM_BUFSIZE;
- }
- memcpy(tpm->data_buffer, req, reqlen);
- *resplen = tpm_transmit(tpm, tpm->data_buffer, TPM_BUFSIZE);
-
- *resp = malloc(*resplen);
- memcpy(*resp, tpm->data_buffer, *resplen);
- return 0;
-}
-
-#ifdef HAVE_LIBC
-int tpm_tis_open(struct tpm_chip* tpm)
-{
- /* Silently prevent multiple opens */
- if(tpm->fd != -1) {
- return tpm->fd;
- }
-
- tpm->fd = alloc_fd(FTYPE_TPM_TIS);
- printk("tpm_tis_open() -> %d\n", tpm->fd);
- files[tpm->fd].tpm_tis.dev = tpm;
- files[tpm->fd].tpm_tis.offset = 0;
- files[tpm->fd].tpm_tis.respgot = 0;
- return tpm->fd;
-}
-
-int tpm_tis_posix_write(int fd, const uint8_t* buf, size_t count)
-{
- struct tpm_chip* tpm;
- tpm = files[fd].tpm_tis.dev;
-
- if(tpm->locality < 0) {
- printk("tpm_tis_posix_write() failed! locality not set!\n");
- errno = EINPROGRESS;
- return -1;
- }
- if(count == 0) {
- return 0;
- }
-
- /* Return an error if we are already processing a command */
- if(count > TPM_BUFSIZE) {
- count = TPM_BUFSIZE;
- }
- /* Send the command now */
- memcpy(tpm->data_buffer, buf, count);
- if((tpm->data_len = tpm_transmit(tpm, tpm->data_buffer, TPM_BUFSIZE)) < 0) {
- errno = EIO;
- return -1;
- }
- return count;
-}
-
-int tpm_tis_posix_read(int fd, uint8_t* buf, size_t count)
-{
- int rc;
- struct tpm_chip* tpm;
- tpm = files[fd].tpm_tis.dev;
-
- if(count == 0) {
- return 0;
- }
-
- /* If there is no tpm resp to read, return EIO */
- if(tpm->data_len < 0) {
- errno = EIO;
- return -1;
- }
-
-
- /* Handle EOF case */
- if(files[fd].tpm_tis.offset >= tpm->data_len) {
- rc = 0;
- } else {
- rc = min(tpm->data_len - files[fd].tpm_tis.offset, count);
- memcpy(buf, tpm->data_buffer + files[fd].tpm_tis.offset, rc);
- }
- files[fd].tpm_tis.offset += rc;
- /* Reset the data pending flag */
- return rc;
-}
-int tpm_tis_posix_fstat(int fd, struct stat* buf)
-{
- struct tpm_chip* tpm;
- tpm = files[fd].tpm_tis.dev;
-
- buf->st_mode = O_RDWR;
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_size = be32_to_cpu(*((uint32_t*)(tpm->data_buffer + 2)));
- buf->st_atime = buf->st_mtime = buf->st_ctime = time(NULL);
- return 0;
-}
-
-/* TPM 2.0 */
-
-/*TPM2.0 Selftest*/
-static void tpm2_selftest(struct tpm_chip* chip)
-{
- uint8_t data[] = {
- 0x80, 0x1,
- 0x0, 0x0, 0x0, 0xb,
- 0x0, 0x0, 0x1, 0x43,
- 0x1,
- };
-
- tpm_transmit(chip, data, sizeof(data));
-}
-
-struct tpm_chip* init_tpm2_tis(unsigned long baseaddr, int localities, unsigned int irq)
-{
- int i;
- unsigned long addr;
- struct tpm_chip* tpm = NULL;
- uint32_t didvid;
- uint32_t intfcaps;
- uint32_t intmask;
-
- printk("============= Init TPM2 TIS Driver ==============\n");
-
- /*Sanity check the localities input */
- if (localities & ~TPM_TIS_EN_LOCLALL) {
- printk("init_tpm2_tis Invalid locality specification! %X\n", localities);
- goto abort_egress;
- }
-
- printk("IOMEM Machine Base Address: %lX\n", baseaddr);
-
- /* Create the tpm data structure */
- tpm = malloc(sizeof(struct tpm_chip));
- __init_tpm_chip(tpm);
-
- /* Set the enabled localities - if 0 we leave default as all enabled */
- if (localities != 0) {
- tpm->enabled_localities = localities;
- }
- printk("Enabled Localities: ");
- for (i = 0; i < 5; ++i) {
- if (locality_enabled(tpm, i)) {
- printk("%d ", i);
- }
- }
- printk("\n");
-
- /* Set the base machine address */
- tpm->baseaddr = baseaddr;
-
- /* Set default timeouts */
- tpm->timeout_a = MILLISECS(TIS_SHORT_TIMEOUT);
- tpm->timeout_b = MILLISECS(TIS_LONG_TIMEOUT);
- tpm->timeout_c = MILLISECS(TIS_SHORT_TIMEOUT);
- tpm->timeout_d = MILLISECS(TIS_SHORT_TIMEOUT);
-
- /*Map the mmio pages */
- addr = tpm->baseaddr;
- for (i = 0; i < 5; ++i) {
- if (locality_enabled(tpm, i)) {
-
- /* Map the page in now */
- if ((tpm->pages[i] = ioremap_nocache(addr, PAGE_SIZE)) == NULL) {
- printk("Unable to map iomem page a address %p\n", addr);
- goto abort_egress;
- }
-
- /* Set default locality to the first enabled one */
- if (tpm->locality < 0) {
- if (tpm_tis_request_locality(tpm, i) < 0) {
- printk("Unable to request locality %d??\n", i);
- goto abort_egress;
- }
- }
- }
- addr += PAGE_SIZE;
- }
-
- /* Get the vendor and device ids */
- didvid = ioread32(TPM_DID_VID(tpm, tpm->locality));
- tpm->did = didvid >> 16;
- tpm->vid = didvid & 0xFFFF;
-
- /* Get the revision id */
- tpm->rid = ioread8(TPM_RID(tpm, tpm->locality));
- printk("2.0 TPM (device-id=0x%X vendor-id = %X rev-id = %X)\n",
- tpm->did, tpm->vid, tpm->rid);
-
- intfcaps = ioread32(TPM_INTF_CAPS(tpm, tpm->locality));
- printk("TPM interface capabilities (0x%x):\n", intfcaps);
- if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
- printk("\tBurst Count Static\n");
- if (intfcaps & TPM_INTF_CMD_READY_INT)
- printk("\tCommand Ready Int Support\n");
- if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
- printk("\tInterrupt Edge Falling\n");
- if (intfcaps & TPM_INTF_INT_EDGE_RISING)
- printk("\tInterrupt Edge Rising\n");
- if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
- printk("\tInterrupt Level Low\n");
- if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
- printk("\tInterrupt Level High\n");
- if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
- printk("\tLocality Change Int Support\n");
- if (intfcaps & TPM_INTF_STS_VALID_INT)
- printk("\tSts Valid Int Support\n");
- if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
- printk("\tData Avail Int Support\n");
-
- /*Interupt setup */
- intmask = ioread32(TPM_INT_ENABLE(tpm, tpm->locality));
-
- intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
- TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
-
- iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask);
-
- /*If interupts are enabled, handle it */
- if (irq) {
- if (irq != TPM_PROBE_IRQ) {
- tpm->irq = irq;
- } else {
- /*FIXME add irq probing feature later */
- printk("IRQ probing not implemented\n");
- }
- }
-
- if (tpm->irq) {
- iowrite8(TPM_INT_VECTOR(tpm, tpm->locality), tpm->irq);
- if (bind_pirq(tpm->irq, 1, tpm_tis_irq_handler, tpm) != 0) {
- printk("Unabled to request irq: %u for use\n", tpm->irq);
- printk("Will use polling mode\n");
- tpm->irq = 0;
- } else {
-
- /* Clear all existing */
- iowrite32(TPM_INT_STATUS(tpm, tpm->locality),
- ioread32(TPM_INT_STATUS(tpm, tpm->locality)));
-
- /* Turn on interrupts */
- iowrite32(TPM_INT_ENABLE(tpm, tpm->locality),
- intmask | TPM_GLOBAL_INT_ENABLE);
- }
- }
-
- tpm2_selftest(tpm);
- return tpm;
-
-abort_egress:
- if (tpm != NULL) {
- shutdown_tpm_tis(tpm);
- }
- return NULL;
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/xen/tpmback/tpmback.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself derived from drivers/xen/netback/netback.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This code has also been derived from drivers/xen/tpmback/xenbus.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (C) 2005 IBM Corporation
- * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
- *
- * This code has also been derived from drivers/xen/tpmback/interface.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself also derived from drvivers/xen/netback/interface.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2004, Keir Fraser
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, version 2
- * of the License
- */
-#include <mini-os/os.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <errno.h>
-#include <mini-os/gnttab.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/tpmif.h>
-#include <xen/io/protocols.h>
-#include <mini-os/xmalloc.h>
-#include <time.h>
-#include <mini-os/tpmback.h>
-#include <mini-os/lib.h>
-#include <fcntl.h>
-#include <mini-os/mm.h>
-#include <mini-os/posix/sys/mman.h>
-#include <mini-os/semaphore.h>
-#include <mini-os/wait.h>
-
-
-#ifndef HAVE_LIBC
-#define strtoul simple_strtoul
-#endif
-
-//#define TPMBACK_PRINT_DEBUG
-#ifdef TPMBACK_PRINT_DEBUG
-#define TPMBACK_DEBUG(fmt,...) printk("Tpmback:Debug("__FILE__":%d) " fmt, __LINE__, ##__VA_ARGS__)
-#define TPMBACK_DEBUG_MORE(fmt,...) printk(fmt, ##__VA_ARGS__)
-#else
-#define TPMBACK_DEBUG(fmt,...)
-#endif
-#define TPMBACK_ERR(fmt,...) printk("Tpmback:Error " fmt, ##__VA_ARGS__)
-#define TPMBACK_LOG(fmt,...) printk("Tpmback:Info " fmt, ##__VA_ARGS__)
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-
-/* Default size of the tpmif array at initialization */
-#define DEF_ARRAY_SIZE 1
-
-/* tpmif and tpmdev flags */
-#define TPMIF_CLOSED 1
-#define TPMIF_REQ_READY 2
-
-struct tpmif {
- domid_t domid;
- unsigned int handle;
-
- char* fe_path;
- char* fe_state_path;
-
- /* Locally bound event channel*/
- evtchn_port_t evtchn;
-
- /* Shared page */
- tpmif_shared_page_t *page;
-
- enum xenbus_state state;
- enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-
- unsigned char uuid[16];
- void* opaque;
-
- /* state flags */
- int flags;
-};
-typedef struct tpmif tpmif_t;
-
-struct tpmback_dev {
-
- tpmif_t** tpmlist;
- unsigned long num_tpms;
- unsigned long num_alloc;
-
- struct gntmap map;
-
- /* True if at least one tpmif has a request to be handled */
- int flags;
-
- xenbus_event_queue events;
-
- /* Callbacks */
- void (*open_callback)(domid_t, unsigned int);
- void (*close_callback)(domid_t, unsigned int);
-};
-typedef struct tpmback_dev tpmback_dev_t;
-
-enum { EV_NONE, EV_NEWFE, EV_STCHNG } tpm_ev_enum;
-
-/* Global objects */
-static struct thread* eventthread = NULL;
-static tpmback_dev_t gtpmdev = {
- .tpmlist = NULL,
- .num_tpms = 0,
- .num_alloc = 0,
- .flags = TPMIF_CLOSED,
- .events = NULL,
- .open_callback = NULL,
- .close_callback = NULL,
-};
-struct wait_queue_head waitq;
-int globalinit = 0;
-
-/************************************
- * TPMIF SORTED ARRAY FUNCTIONS
- * tpmback_dev_t.tpmlist is a sorted array, sorted by domid and then handle number
- * Duplicates are not allowed
- * **********************************/
-
-static void tpmif_req_ready(tpmif_t* tpmif) {
- tpmif->flags |= TPMIF_REQ_READY;
- gtpmdev.flags |= TPMIF_REQ_READY;
-}
-
-static void tpmdev_check_req(void) {
- int i;
- int flags;
- local_irq_save(flags);
- for(i = 0; i < gtpmdev.num_tpms; ++i) {
- if(gtpmdev.tpmlist[i]->flags & TPMIF_REQ_READY) {
- gtpmdev.flags |= TPMIF_REQ_READY;
- local_irq_restore(flags);
- return;
- }
- }
- gtpmdev.flags &= ~TPMIF_REQ_READY;
- local_irq_restore(flags);
-}
-
-static void tpmif_req_finished(tpmif_t* tpmif) {
- tpmif->flags &= ~TPMIF_REQ_READY;
- tpmdev_check_req();
-}
-
-int __get_tpmif_index(int st, int n, domid_t domid, unsigned int handle)
-{
- int i = st + n /2;
- tpmif_t* tmp;
-
- if( n <= 0 )
- return -1;
-
- tmp = gtpmdev.tpmlist[i];
- if(domid == tmp->domid && tmp->handle == handle) {
- return i;
- } else if ( (domid < tmp->domid) ||
- (domid == tmp->domid && handle < tmp->handle)) {
- return __get_tpmif_index(st, n/2, domid, handle);
- } else {
- return __get_tpmif_index(i + 1, n/2 - ((n +1) % 2), domid, handle);
- }
-}
-
-/* Returns the array index of the tpmif domid/handle. Returns -1 if no such tpmif exists */
-int get_tpmif_index(domid_t domid, unsigned int handle)
-{
- int flags;
- int index;
- local_irq_save(flags);
- index = __get_tpmif_index(0, gtpmdev.num_tpms, domid, handle);
- local_irq_restore(flags);
- return index;
-}
-
-/* Returns the tpmif domid/handle or NULL if none exists */
-tpmif_t* get_tpmif(domid_t domid, unsigned int handle)
-{
- int flags;
- int i;
- tpmif_t* ret;
- local_irq_save(flags);
- i = get_tpmif_index(domid, handle);
- if (i < 0) {
- ret = NULL;
- } else {
- ret = gtpmdev.tpmlist[i];
- }
- local_irq_restore(flags);
- return ret;
-}
-
-/* Remove the given tpmif. Returns 0 if it was removed, -1 if it was not removed */
-int remove_tpmif(tpmif_t* tpmif)
-{
- int i, j;
- char* err;
- int flags;
- local_irq_save(flags);
-
- /* Find the index in the array if it exists */
- i = get_tpmif_index(tpmif->domid, tpmif->handle);
- if (i < 0) {
- goto error;
- }
-
- /* Remove the interface from the list */
- for(j = i; j < gtpmdev.num_tpms - 1; ++j) {
- gtpmdev.tpmlist[j] = gtpmdev.tpmlist[j+1];
- }
- gtpmdev.tpmlist[j] = NULL;
- --gtpmdev.num_tpms;
-
- /* If removed tpm was the only ready tpm, then we need to check and turn off the ready flag */
- tpmdev_check_req();
-
- local_irq_restore(flags);
-
- /* Stop listening for events on this tpm interface */
- if((err = xenbus_unwatch_path_token(XBT_NIL, tpmif->fe_state_path, tpmif->fe_state_path))) {
- TPMBACK_ERR("Unable to unwatch path token `%s' Error was %s Ignoring..\n", tpmif->fe_state_path, err);
- free(err);
- }
-
- return 0;
-error:
- local_irq_restore(flags);
- return -1;
-}
-
-/* Insert tpmif into dev->tpmlist. Returns 0 on success and non zero on error.
- * It is an error to insert a tpmif with the same domid and handle
- * number
- * as something already in the list */
-int insert_tpmif(tpmif_t* tpmif)
-{
- int flags;
- unsigned int i, j;
- tpmif_t* tmp;
- char* err;
- char path[512];
-
- local_irq_save(flags);
-
- /*Check if we need to allocate more space */
- if (gtpmdev.num_tpms == gtpmdev.num_alloc) {
- gtpmdev.num_alloc *= 2;
- gtpmdev.tpmlist = realloc(gtpmdev.tpmlist, gtpmdev.num_alloc);
- }
-
- /*Find where to put the new interface */
- for(i = 0; i < gtpmdev.num_tpms; ++i)
- {
- tmp = gtpmdev.tpmlist[i];
- if(tpmif->domid == tmp->domid && tpmif->handle == tmp->handle) {
- TPMBACK_ERR("Tried to insert duplicate tpm interface %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- goto error;
- }
- if((tpmif->domid < tmp->domid) ||
- (tpmif->domid == tmp->domid && tpmif->handle < tmp->handle)) {
- break;
- }
- }
-
- /*Shift all the tpm pointers past i down one */
- for(j = gtpmdev.num_tpms; j > i; --j) {
- gtpmdev.tpmlist[j] = gtpmdev.tpmlist[j-1];
- }
-
- /*Add the new interface */
- gtpmdev.tpmlist[i] = tpmif;
- ++gtpmdev.num_tpms;
-
- /*Should not be needed, anything inserted with ready flag is probably an error */
- tpmdev_check_req();
-
- local_irq_restore(flags);
-
- snprintf(path, 512, "backend/vtpm/%u/%u/feature-protocol-v2", (unsigned int) tpmif->domid, tpmif->handle);
- if ((err = xenbus_write(XBT_NIL, path, "1")))
- {
- /* if we got an error here we should carefully remove the interface and then return */
- TPMBACK_ERR("Unable to write feature-protocol-v2 node: %s\n", err);
- free(err);
- remove_tpmif(tpmif);
- goto error_post_irq;
- }
-
- /*Listen for state changes on the new interface */
- if((err = xenbus_watch_path_token(XBT_NIL, tpmif->fe_state_path, tpmif->fe_state_path, >pmdev.events)))
- {
- /* if we got an error here we should carefully remove the interface and then return */
- TPMBACK_ERR("Unable to watch path token `%s' Error was %s\n", tpmif->fe_state_path, err);
- free(err);
- remove_tpmif(tpmif);
- goto error_post_irq;
- }
- return 0;
-error:
- local_irq_restore(flags);
-error_post_irq:
- return -1;
-}
-
-
-/*****************
- * CHANGE BACKEND STATE
- * *****************/
-/*Attempts to change the backend state in xenstore
- * returns 0 on success and non-zero on error */
-int tpmif_change_state(tpmif_t* tpmif, enum xenbus_state state)
-{
- int tempst;
- char path[512];
- char *value;
- char *err;
- enum xenbus_state readst;
- TPMBACK_DEBUG("Backend state change %u/%u from=%d to=%d\n", (unsigned int) tpmif->domid, tpmif->handle, tpmif->state, state);
- if (tpmif->state == state)
- return 0;
-
- snprintf(path, 512, "backend/vtpm/%u/%u/state", (unsigned int) tpmif->domid, tpmif->handle);
-
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMBACK_ERR("Unable to read backend state %s, error was %s\n", path, err);
- free(err);
- return -1;
- }
- if(sscanf(value, "%d", &tempst) != 1) {
- TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
- free(value);
- return -1;
- }
- readst = (enum xenbus_state) tempst;
- free(value);
-
- /* It's possible that the backend state got updated by hotplug or something else behind our back */
- if(readst != tpmif->state) {
- TPMBACK_DEBUG("tpm interface state was %d but xenstore state was %d!\n", tpmif->state, readst);
- tpmif->state = readst;
- }
-
- /*If if the state isnt changing, then we dont update xenstore b/c we dont want to fire extraneous events */
- if(tpmif->state == state) {
- return 0;
- }
-
- /*update xenstore*/
- snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, tpmif->handle);
- if((err = xenbus_printf(XBT_NIL, path, "state", "%u", state))) {
- TPMBACK_ERR("Error writing to xenstore %s, error was %s new state=%d\n", path, err, state);
- free(err);
- return -1;
- }
-
- tpmif->state = state;
-
- return 0;
-}
-/**********************************
- * TPMIF CREATION AND DELETION
- * *******************************/
-static tpmif_t* __init_tpmif(domid_t domid, unsigned int handle)
-{
- tpmif_t* tpmif;
- tpmif = malloc(sizeof(*tpmif));
- tpmif->domid = domid;
- tpmif->handle = handle;
- tpmif->fe_path = NULL;
- tpmif->fe_state_path = NULL;
- tpmif->state = XenbusStateInitialising;
- tpmif->status = DISCONNECTED;
- tpmif->page = NULL;
- tpmif->flags = 0;
- tpmif->opaque = NULL;
- memset(tpmif->uuid, 0, sizeof(tpmif->uuid));
- return tpmif;
-}
-
-void __free_tpmif(tpmif_t* tpmif)
-{
- if(tpmif->fe_path) {
- free(tpmif->fe_path);
- }
- if(tpmif->fe_state_path) {
- free(tpmif->fe_state_path);
- }
- free(tpmif);
-}
-/* Creates a new tpm interface, adds it to the sorted array and returns it.
- * returns NULL on error
- * If the tpm interface already exists, it is returned*/
-tpmif_t* new_tpmif(domid_t domid, unsigned int handle)
-{
- tpmif_t* tpmif;
- char* err;
- char path[512];
-
- /* Make sure we haven't already created this tpm
- * Double events can occur */
- if((tpmif = get_tpmif(domid, handle)) != NULL) {
- return tpmif;
- }
-
- tpmif = __init_tpmif(domid, handle);
-
- /* Get the uuid from xenstore */
- snprintf(path, 512, "backend/vtpm/%u/%u/uuid", (unsigned int) domid, handle);
- if((!xenbus_read_uuid(path, tpmif->uuid))) {
- TPMBACK_ERR("Error reading %s\n", path);
- goto error;
- }
-
- if(tpmif_change_state(tpmif, XenbusStateInitWait)) {
- goto error;
- }
-
- snprintf(path, 512, "backend/vtpm/%u/%u/frontend", (unsigned int) domid, handle);
- if((err = xenbus_read(XBT_NIL, path, &tpmif->fe_path))) {
- TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s), Error = %s", path, err);
- free(err);
- goto error;
- }
-
- /*Set the state path */
- tpmif->fe_state_path = malloc(strlen(tpmif->fe_path) + 7);
- strcpy(tpmif->fe_state_path, tpmif->fe_path);
- strcat(tpmif->fe_state_path, "/state");
-
- if(insert_tpmif(tpmif)) {
- goto error;
- }
- TPMBACK_DEBUG("New tpmif %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- /* Do the callback now */
- if(gtpmdev.open_callback) {
- gtpmdev.open_callback(tpmif->domid, tpmif->handle);
- }
- return tpmif;
-error:
- __free_tpmif(tpmif);
- return NULL;
-
-}
-
-/* Removes tpmif from dev->tpmlist and frees it's memory usage */
-void free_tpmif(tpmif_t* tpmif)
-{
- char* err;
- char path[512];
- TPMBACK_DEBUG("Free tpmif %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- if(tpmif->flags & TPMIF_CLOSED) {
- TPMBACK_ERR("Tried to free an instance twice! Theres a bug somewhere!\n");
- BUG();
- }
- tpmif->flags = TPMIF_CLOSED;
-
- tpmif_change_state(tpmif, XenbusStateClosing);
-
- /* Unmap share page and unbind event channel */
- if(tpmif->status == CONNECTED) {
- tpmif->status = DISCONNECTING;
- mask_evtchn(tpmif->evtchn);
-
- if(gntmap_munmap(>pmdev.map, (unsigned long)tpmif->page, 1)) {
- TPMBACK_ERR("%u/%u Error occured while trying to unmap shared page\n", (unsigned int) tpmif->domid, tpmif->handle);
- }
-
- unbind_evtchn(tpmif->evtchn);
- }
- tpmif->status = DISCONNECTED;
- tpmif_change_state(tpmif, XenbusStateClosed);
-
- /* Do the callback now */
- if(gtpmdev.close_callback) {
- gtpmdev.close_callback(tpmif->domid, tpmif->handle);
- }
-
- /* remove from array */
- remove_tpmif(tpmif);
-
- /* Wake up anyone possibly waiting on this interface and let them exit */
- wake_up(&waitq);
- schedule();
-
- /* Remove the old xenbus entries */
- snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, tpmif->handle);
- if((err = xenbus_rm(XBT_NIL, path))) {
- TPMBACK_ERR("Error cleaning up xenbus entries path=%s error=%s\n", path, err);
- free(err);
- }
-
- TPMBACK_LOG("Frontend %u/%u disconnected\n", (unsigned int) tpmif->domid, tpmif->handle);
-
- /* free memory */
- __free_tpmif(tpmif);
-
-}
-
-/**********************
- * REMAINING TPMBACK FUNCTIONS
- * ********************/
-
-/*Event channel handler */
-void tpmback_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
- tpmif_t* tpmif = (tpmif_t*) data;
- tpmif_shared_page_t *pg = tpmif->page;
-
- switch (pg->state)
- {
- case TPMIF_STATE_SUBMIT:
- TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- tpmif_req_ready(tpmif);
- wake_up(&waitq);
- break;
- case TPMIF_STATE_CANCEL:
- /* If we are busy with a request, do nothing */
- if (tpmif->flags & TPMIF_REQ_READY)
- return;
- /* Acknowledge the cancellation if we are idle */
- pg->state = TPMIF_STATE_IDLE;
- wmb();
- notify_remote_via_evtchn(tpmif->evtchn);
- return;
- default:
- /* Spurious wakeup; do nothing */
- return;
- }
-}
-
-/* Connect to frontend */
-int connect_fe(tpmif_t* tpmif)
-{
- char path[512];
- char* err, *value;
- uint32_t domid;
- grant_ref_t ringref;
- evtchn_port_t evtchn;
-
- /* If already connected then quit */
- if (tpmif->status == CONNECTED) {
- TPMBACK_DEBUG("%u/%u tried to connect while it was already connected?\n", (unsigned int) tpmif->domid, tpmif->handle);
- return 0;
- }
-
- /* Fetch the grant reference */
- snprintf(path, 512, "%s/ring-ref", tpmif->fe_path);
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s) Error = %s", path, err);
- free(err);
- return -1;
- }
- if(sscanf(value, "%d", &ringref) != 1) {
- TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
- free(value);
- return -1;
- }
- free(value);
-
-
- /* Fetch the event channel*/
- snprintf(path, 512, "%s/event-channel", tpmif->fe_path);
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s) Error = %s", path, err);
- free(err);
- return -1;
- }
- if(sscanf(value, "%d", &evtchn) != 1) {
- TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
- free(value);
- return -1;
- }
- free(value);
-
- /* Check that protocol v2 is being used */
- snprintf(path, 512, "%s/feature-protocol-v2", tpmif->fe_path);
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMBACK_ERR("Unable to read %s during tpmback initialization! error = %s\n", path, err);
- free(err);
- return -1;
- }
- if(strcmp(value, "1")) {
- TPMBACK_ERR("%s has an invalid value (%s)\n", path, value);
- free(value);
- return -1;
- }
- free(value);
-
- domid = tpmif->domid;
- if((tpmif->page = gntmap_map_grant_refs(>pmdev.map, 1, &domid, 0, &ringref, PROT_READ | PROT_WRITE)) == NULL) {
- TPMBACK_ERR("Failed to map grant reference %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- return -1;
- }
-
- /*Bind the event channel */
- if((evtchn_bind_interdomain(tpmif->domid, evtchn, tpmback_handler, tpmif, &tpmif->evtchn)))
- {
- TPMBACK_ERR("%u/%u Unable to bind to interdomain event channel!\n", (unsigned int) tpmif->domid, tpmif->handle);
- goto error_post_map;
- }
- unmask_evtchn(tpmif->evtchn);
-
- /* Write the ready flag and change status to connected */
- snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, tpmif->handle);
- if((err = xenbus_printf(XBT_NIL, path, "ready", "%u", 1))) {
- TPMBACK_ERR("%u/%u Unable to write ready flag on connect_fe()\n", (unsigned int) tpmif->domid, tpmif->handle);
- free(err);
- goto error_post_evtchn;
- }
- tpmif->status = CONNECTED;
- if((tpmif_change_state(tpmif, XenbusStateConnected))){
- goto error_post_evtchn;
- }
-
- TPMBACK_LOG("Frontend %u/%u connected\n", (unsigned int) tpmif->domid, tpmif->handle);
-
- return 0;
-error_post_evtchn:
- mask_evtchn(tpmif->evtchn);
- unbind_evtchn(tpmif->evtchn);
-error_post_map:
- gntmap_munmap(>pmdev.map, (unsigned long)tpmif->page, 1);
- return -1;
-}
-
-static void disconnect_fe(tpmif_t* tpmif)
-{
- if (tpmif->status == CONNECTED) {
- tpmif->status = DISCONNECTING;
- mask_evtchn(tpmif->evtchn);
-
- if(gntmap_munmap(>pmdev.map, (unsigned long)tpmif->page, 1)) {
- TPMBACK_ERR("%u/%u Error occured while trying to unmap shared page\n", (unsigned int) tpmif->domid, tpmif->handle);
- }
-
- unbind_evtchn(tpmif->evtchn);
- }
- tpmif->status = DISCONNECTED;
- tpmif_change_state(tpmif, XenbusStateInitWait);
-
- TPMBACK_LOG("Frontend %u/%u disconnected\n", (unsigned int) tpmif->domid, tpmif->handle);
-}
-
-static int frontend_changed(tpmif_t* tpmif)
-{
- int state = xenbus_read_integer(tpmif->fe_state_path);
- if(state < 0) {
- state = XenbusStateUnknown;
- }
-
- TPMBACK_DEBUG("Frontend %u/%u state changed to %d\n", (unsigned int) tpmif->domid, tpmif->handle, state);
-
- switch (state) {
- case XenbusStateInitialising:
- break;
-
- case XenbusStateInitialised:
- case XenbusStateConnected:
- if(connect_fe(tpmif)) {
- TPMBACK_ERR("Failed to connect to front end %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
- tpmif_change_state(tpmif, XenbusStateClosed);
- return -1;
- }
- break;
-
- case XenbusStateClosing:
- tpmif_change_state(tpmif, XenbusStateClosing);
- break;
-
- case XenbusStateClosed:
- disconnect_fe(tpmif);
- break;
-
- case XenbusStateUnknown: /* keep it here */
- free_tpmif(tpmif);
- break;
-
- default:
- TPMBACK_DEBUG("BAD STATE CHANGE %u/%u state = %d for tpmif\n", (unsigned int) tpmif->domid, tpmif->handle, state);
- return -1;
- }
- return 0;
-}
-
-
-/* parses the string that comes out of xenbus_watch_wait_return. */
-static int parse_eventstr(const char* evstr, domid_t* domid, unsigned int* handle)
-{
- int ret;
- char cmd[40];
- char* err;
- char* value;
- unsigned int udomid = 0;
- tpmif_t* tpmif;
- /* First check for new frontends, this occurs when /backend/vtpm/<domid>/<handle> gets created. Note we what the sscanf to fail on the last %s */
- if (sscanf(evstr, "backend/vtpm/%u/%u/%40s", &udomid, handle, cmd) == 2) {
- *domid = udomid;
- /* Make sure the entry exists, if this event triggers because the entry dissapeared then ignore it */
- if((err = xenbus_read(XBT_NIL, evstr, &value))) {
- free(err);
- return EV_NONE;
- }
- free(value);
- /* Make sure the tpmif entry does not already exist, this should not happen */
- if((tpmif = get_tpmif(*domid, *handle)) != NULL) {
- TPMBACK_DEBUG("Duplicate tpm entries! %u %u\n", tpmif->domid, tpmif->handle);
- return EV_NONE;
- }
- return EV_NEWFE;
- } else if((ret = sscanf(evstr, "/local/domain/%u/device/vtpm/%u/%40s", &udomid, handle, cmd)) == 3) {
- *domid = udomid;
- if (!strcmp(cmd, "state"))
- return EV_STCHNG;
- }
- return EV_NONE;
-}
-
-void handle_backend_event(char* evstr) {
- tpmif_t* tpmif;
- domid_t domid;
- unsigned int handle;
- int event;
-
- TPMBACK_DEBUG("Xenbus Event: %s\n", evstr);
-
- event = parse_eventstr(evstr, &domid, &handle);
-
- switch(event) {
- case EV_NEWFE:
- if(new_tpmif(domid, handle) == NULL) {
- TPMBACK_ERR("Failed to create new tpm instance %u/%u\n", (unsigned int) domid, handle);
- }
- wake_up(&waitq);
- break;
- case EV_STCHNG:
- if((tpmif = get_tpmif(domid, handle))) {
- frontend_changed(tpmif);
- } else {
- TPMBACK_DEBUG("Event Received for non-existant tpm! instance=%u/%u xenbus_event=%s\n", (unsigned int) domid, handle, evstr);
- }
- break;
- }
-}
-
-/* Runs through the given path and creates events recursively
- * for all of its children.
- * @path - xenstore path to scan */
-static void generate_backend_events(const char* path)
-{
- char* err;
- int i, len;
- char **dirs;
- char *entry;
-
- if((err = xenbus_ls(XBT_NIL, path, &dirs)) != NULL) {
- free(err);
- return;
- }
-
- for(i = 0; dirs[i] != NULL; ++i) {
- len = strlen(path) + strlen(dirs[i]) + 2;
- entry = malloc(len);
- snprintf(entry, len, "%s/%s", path, dirs[i]);
-
- /* Generate and handle event for the entry itself */
- handle_backend_event(entry);
-
- /* Do children */
- generate_backend_events(entry);
-
- /* Cleanup */
- free(entry);
- free(dirs[i]);
- }
- free(dirs);
- return;
-}
-
-void* tpmback_get_opaque(domid_t domid, unsigned int handle)
-{
- tpmif_t* tpmif;
- if((tpmif = get_tpmif(domid, handle)) == NULL) {
- TPMBACK_DEBUG("get_opaque() failed, %u/%u is an invalid frontend\n", (unsigned int) domid, handle);
- return NULL;
- }
-
- return tpmif->opaque;
-}
-
-int tpmback_set_opaque(domid_t domid, unsigned int handle, void *opaque)
-{
- tpmif_t* tpmif;
- if((tpmif = get_tpmif(domid, handle)) == NULL) {
- TPMBACK_DEBUG("set_opaque() failed, %u/%u is an invalid frontend\n", (unsigned int) domid, handle);
- return -1;
- }
-
- tpmif->opaque = opaque;
- return 0;
-}
-
-unsigned char* tpmback_get_uuid(domid_t domid, unsigned int handle)
-{
- tpmif_t* tpmif;
- if((tpmif = get_tpmif(domid, handle)) == NULL) {
- TPMBACK_DEBUG("get_uuid() failed, %u/%u is an invalid frontend\n", (unsigned int) domid, handle);
- return NULL;
- }
-
- return tpmif->uuid;
-}
-
-int tpmback_get_peercontext(domid_t domid, unsigned int handle, void* buffer, int buflen)
-{
- tpmif_t* tpmif;
- if((tpmif = get_tpmif(domid, handle)) == NULL) {
- TPMBACK_DEBUG("get_uuid() failed, %u/%u is an invalid frontend\n", (unsigned int) domid, handle);
- return -1;
- }
-
- return evtchn_get_peercontext(tpmif->evtchn, buffer, buflen);
-}
-
-static void event_listener(void)
-{
- const char* bepath = "backend/vtpm";
- char **path;
- char* err;
-
- /* Setup the backend device watch */
- if((err = xenbus_watch_path_token(XBT_NIL, bepath, bepath, >pmdev.events)) != NULL) {
- TPMBACK_ERR("xenbus_watch_path_token(%s) failed with error %s!\n", bepath, err);
- free(err);
- goto egress;
- }
-
- /* Check for any frontends that connected before we set the watch.
- * This is almost guaranteed to happen if both domains are started
- * immediatly one after the other.
- * We do this by manually generating events on everything in the backend
- * path */
- generate_backend_events(bepath);
-
- /* Wait and listen for changes in frontend connections */
- while(1) {
- path = xenbus_wait_for_watch_return(>pmdev.events);
-
- /*If quit flag was set then exit */
- if(gtpmdev.flags & TPMIF_CLOSED) {
- TPMBACK_DEBUG("listener thread got quit event. Exiting..\n");
- free(path);
- break;
- }
- handle_backend_event(*path);
- free(path);
-
- }
-
- if((err = xenbus_unwatch_path_token(XBT_NIL, bepath, bepath)) != NULL) {
- free(err);
- }
-egress:
- return;
-}
-
-void event_thread(void* p) {
- event_listener();
-}
-
-void init_tpmback(void (*open_cb)(domid_t, unsigned int), void (*close_cb)(domid_t, unsigned int))
-{
- if(!globalinit) {
- init_waitqueue_head(&waitq);
- globalinit = 1;
- }
- printk("============= Init TPM BACK ================\n");
- gtpmdev.tpmlist = malloc(sizeof(tpmif_t*) * DEF_ARRAY_SIZE);
- gtpmdev.num_alloc = DEF_ARRAY_SIZE;
- gtpmdev.num_tpms = 0;
- gtpmdev.flags = 0;
-
- gtpmdev.open_callback = open_cb;
- gtpmdev.close_callback = close_cb;
-
- eventthread = create_thread("tpmback-listener", event_thread, NULL);
-
-}
-
-void shutdown_tpmback(void)
-{
- TPMBACK_LOG("Shutting down tpm backend\n");
- /* Set the quit flag */
- gtpmdev.flags = TPMIF_CLOSED;
-
- //printk("num tpms is %d\n", gtpmdev.num_tpms);
- /*Free all backend instances */
- while(gtpmdev.num_tpms) {
- free_tpmif(gtpmdev.tpmlist[0]);
- }
- free(gtpmdev.tpmlist);
- gtpmdev.tpmlist = NULL;
- gtpmdev.num_alloc = 0;
-
- /* Wake up anyone possibly waiting on the device and let them exit */
- wake_up(&waitq);
- schedule();
-}
-
-static void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t domid, unsigned int handle, void *opaque)
-{
- tpmcmd->domid = domid;
- tpmcmd->locality = -1;
- tpmcmd->handle = handle;
- tpmcmd->opaque = opaque;
- tpmcmd->req = NULL;
- tpmcmd->req_len = 0;
- tpmcmd->resp = NULL;
- tpmcmd->resp_len = 0;
-}
-
-tpmcmd_t* get_request(tpmif_t* tpmif) {
- tpmcmd_t* cmd;
- tpmif_shared_page_t *shr;
- unsigned int offset;
- int flags;
-#ifdef TPMBACK_PRINT_DEBUG
- int i;
-#endif
-
- local_irq_save(flags);
-
- /* Allocate the cmd object to hold the data */
- if((cmd = malloc(sizeof(*cmd))) == NULL) {
- goto error;
- }
- init_tpmcmd(cmd, tpmif->domid, tpmif->handle, tpmif->opaque);
-
- shr = tpmif->page;
- cmd->req_len = shr->length;
- cmd->locality = shr->locality;
- offset = sizeof(*shr) + 4*shr->nr_extra_pages;
- if (offset > PAGE_SIZE || offset + cmd->req_len > PAGE_SIZE) {
- TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (unsigned int) tpmif->domid, tpmif->handle);
- goto error;
- }
- /* Allocate the buffer */
- if(cmd->req_len) {
- if((cmd->req = malloc(cmd->req_len)) == NULL) {
- goto error;
- }
- }
- /* Copy the bits from the shared page(s) */
- memcpy(cmd->req, offset + (uint8_t*)shr, cmd->req_len);
-
-#ifdef TPMBACK_PRINT_DEBUG
- TPMBACK_DEBUG("Received Tpm Command from %u/%u of size %u", (unsigned int) tpmif->domid, tpmif->handle, cmd->req_len);
- for(i = 0; i < cmd->req_len; ++i) {
- if (!(i % 30)) {
- TPMBACK_DEBUG_MORE("\n");
- }
- TPMBACK_DEBUG_MORE("%02hhX ", cmd->req[i]);
- }
- TPMBACK_DEBUG_MORE("\n\n");
-#endif
-
- local_irq_restore(flags);
- return cmd;
-error:
- if(cmd != NULL) {
- if (cmd->req != NULL) {
- free(cmd->req);
- cmd->req = NULL;
- }
- free(cmd);
- cmd = NULL;
- }
- local_irq_restore(flags);
- return NULL;
-
-}
-
-void send_response(tpmcmd_t* cmd, tpmif_t* tpmif)
-{
- tpmif_shared_page_t *shr;
- unsigned int offset;
- int flags;
-#ifdef TPMBACK_PRINT_DEBUG
-int i;
-#endif
-
- local_irq_save(flags);
-
- shr = tpmif->page;
- shr->length = cmd->resp_len;
-
- offset = sizeof(*shr) + 4*shr->nr_extra_pages;
- if (offset > PAGE_SIZE || offset + cmd->resp_len > PAGE_SIZE) {
- TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (unsigned int) tpmif->domid, tpmif->handle);
- goto error;
- }
- memcpy(offset + (uint8_t*)shr, cmd->resp, cmd->resp_len);
-
-#ifdef TPMBACK_PRINT_DEBUG
- TPMBACK_DEBUG("Sent response to %u/%u of size %u", (unsigned int) tpmif->domid, tpmif->handle, cmd->resp_len);
- for(i = 0; i < cmd->resp_len; ++i) {
- if (!(i % 30)) {
- TPMBACK_DEBUG_MORE("\n");
- }
- TPMBACK_DEBUG_MORE("%02hhX ", cmd->resp[i]);
- }
- TPMBACK_DEBUG_MORE("\n\n");
-#endif
- /* clear the ready flag and send the event channel notice to the frontend */
- tpmif_req_finished(tpmif);
- barrier();
- shr->state = TPMIF_STATE_FINISH;
- wmb();
- notify_remote_via_evtchn(tpmif->evtchn);
-error:
- local_irq_restore(flags);
- return;
-}
-
-tpmcmd_t* tpmback_req_any(void)
-{
- int i;
- /* Block until something has a request */
- wait_event(waitq, (gtpmdev.flags & (TPMIF_REQ_READY | TPMIF_CLOSED)));
-
- /* Check if were shutting down */
- if(gtpmdev.flags & TPMIF_CLOSED) {
- /* if something was waiting for us to give up the queue so it can shutdown, let it finish */
- schedule();
- return NULL;
- }
-
- for(i = 0; i < gtpmdev.num_tpms; ++i) {
- if(gtpmdev.tpmlist[i]->flags & TPMIF_REQ_READY) {
- return get_request(gtpmdev.tpmlist[i]);
- }
- }
-
- TPMBACK_ERR("backend request ready flag was set but no interfaces were actually ready\n");
- return NULL;
-}
-
-tpmcmd_t* tpmback_req(domid_t domid, unsigned int handle)
-{
- tpmif_t* tpmif;
- tpmif = get_tpmif(domid, handle);
- if(tpmif == NULL) {
- return NULL;
- }
-
- wait_event(waitq, (tpmif->flags & (TPMIF_REQ_READY | TPMIF_CLOSED) || gtpmdev.flags & TPMIF_CLOSED));
-
- /* Check if were shutting down */
- if(tpmif->flags & TPMIF_CLOSED || gtpmdev.flags & TPMIF_CLOSED) {
- /* if something was waiting for us to give up the queue so it can free this instance, let it finish */
- schedule();
- return NULL;
- }
-
- return get_request(tpmif);
-}
-
-void tpmback_resp(tpmcmd_t* tpmcmd)
-{
- tpmif_t* tpmif;
-
- /* Get the associated interface, if it doesnt exist then just quit */
- tpmif = get_tpmif(tpmcmd->domid, tpmcmd->handle);
- if(tpmif == NULL) {
- TPMBACK_ERR("Tried to send a reponse to non existant frontend %u/%u\n", (unsigned int) tpmcmd->domid, tpmcmd->handle);
- goto end;
- }
-
- if(!(tpmif->flags & TPMIF_REQ_READY)) {
- TPMBACK_ERR("Tried to send response to a frontend that was not waiting for one %u/%u\n", (unsigned int) tpmcmd->domid, tpmcmd->handle);
- goto end;
- }
-
- /* Send response to frontend */
- send_response(tpmcmd, tpmif);
-
-end:
- if(tpmcmd->req != NULL) {
- free(tpmcmd->req);
- }
- free(tpmcmd);
- return;
-}
-
-int tpmback_wait_for_frontend_connect(domid_t *domid, unsigned int *handle)
-{
- tpmif_t* tpmif;
- int flags;
- wait_event(waitq, ((gtpmdev.num_tpms > 0) || gtpmdev.flags & TPMIF_CLOSED));
- if(gtpmdev.flags & TPMIF_CLOSED) {
- return -1;
- }
- local_irq_save(flags);
- tpmif = gtpmdev.tpmlist[0];
- *domid = tpmif->domid;
- *handle = tpmif->handle;
- local_irq_restore(flags);
-
- return 0;
-}
-
-int tpmback_num_frontends(void)
-{
- return gtpmdev.num_tpms;
-}
+++ /dev/null
-/*
- * Copyright (c) 2010-2012 United States Government, as represented by
- * the Secretary of Defense. All rights reserved.
- *
- * This code has been derived from drivers/char/tpm_vtpm.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (C) 2006 IBM Corporation
- *
- * This code has also been derived from drivers/char/tpm_xen.c
- * from the xen 2.6.18 linux kernel
- *
- * Copyright (c) 2005, IBM Corporation
- *
- * which was itself derived from drivers/xen/netfront/netfront.c
- * from the linux kernel
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- */
-#include <mini-os/os.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/events.h>
-#include <mini-os/wait.h>
-#include <mini-os/gnttab.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/tpmif.h>
-#include <mini-os/tpmfront.h>
-#include <mini-os/lib.h>
-#include <fcntl.h>
-
-//#define TPMFRONT_PRINT_DEBUG
-#ifdef TPMFRONT_PRINT_DEBUG
-#define TPMFRONT_DEBUG(fmt,...) printk("Tpmfront:Debug("__FILE__":%d) " fmt, __LINE__, ##__VA_ARGS__)
-#define TPMFRONT_DEBUG_MORE(fmt,...) printk(fmt, ##__VA_ARGS__)
-#else
-#define TPMFRONT_DEBUG(fmt,...)
-#endif
-#define TPMFRONT_ERR(fmt,...) printk("Tpmfront:Error " fmt, ##__VA_ARGS__)
-#define TPMFRONT_LOG(fmt,...) printk("Tpmfront:Info " fmt, ##__VA_ARGS__)
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-
-void tpmfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) {
- struct tpmfront_dev* dev = (struct tpmfront_dev*) data;
- tpmif_shared_page_t *shr = dev->page;
- /*If we get a response when we didnt make a request, just ignore it */
- if(!dev->waiting) {
- return;
- }
-
- switch (shr->state) {
- case TPMIF_STATE_FINISH: /* request was completed */
- case TPMIF_STATE_IDLE: /* request was cancelled */
- break;
- default:
- /* Spurious wakeup; do nothing, request is still pending */
- return;
- }
-
- dev->waiting = 0;
-#ifdef HAVE_LIBC
- if(dev->fd >= 0) {
- files[dev->fd].read = 1;
- }
-#endif
- wake_up(&dev->waitq);
-}
-
-static int publish_xenbus(struct tpmfront_dev* dev) {
- xenbus_transaction_t xbt;
- int retry;
- char* err;
- /* Write the grant reference and event channel to xenstore */
-again:
- if((err = xenbus_transaction_start(&xbt))) {
- TPMFRONT_ERR("Unable to start xenbus transaction, error was %s\n", err);
- free(err);
- return -1;
- }
-
- if((err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u", (unsigned int) dev->ring_ref))) {
- TPMFRONT_ERR("Unable to write %s/ring-ref, error was %s\n", dev->nodename, err);
- free(err);
- goto abort_transaction;
- }
-
- if((err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", (unsigned int) dev->evtchn))) {
- TPMFRONT_ERR("Unable to write %s/event-channel, error was %s\n", dev->nodename, err);
- free(err);
- goto abort_transaction;
- }
-
- if((err = xenbus_transaction_end(xbt, 0, &retry))) {
- TPMFRONT_ERR("Unable to complete xenbus transaction, error was %s\n", err);
- free(err);
- return -1;
- }
- if(retry) {
- goto again;
- }
-
- return 0;
-abort_transaction:
- if((err = xenbus_transaction_end(xbt, 1, &retry))) {
- free(err);
- }
- return -1;
-}
-
-static int wait_for_backend_connect(xenbus_event_queue* events, char* path)
-{
- int state;
-
- TPMFRONT_LOG("Waiting for backend connection..\n");
- /* Wait for the backend to connect */
- while(1) {
- state = xenbus_read_integer(path);
- if ( state < 0)
- state = XenbusStateUnknown;
- switch(state) {
- /* Bad states, we quit with error */
- case XenbusStateUnknown:
- case XenbusStateClosing:
- case XenbusStateClosed:
- TPMFRONT_ERR("Unable to connect to backend\n");
- return -1;
- /* If backend is connected then break out of loop */
- case XenbusStateConnected:
- TPMFRONT_LOG("Backend Connected\n");
- return 0;
- default:
- xenbus_wait_for_watch(events);
- }
- }
-
-}
-
-static int wait_for_backend_closed(xenbus_event_queue* events, char* path)
-{
- int state;
-
- TPMFRONT_LOG("Waiting for backend to close..\n");
- while(1) {
- state = xenbus_read_integer(path);
- if ( state < 0)
- state = XenbusStateUnknown;
- switch(state) {
- case XenbusStateUnknown:
- TPMFRONT_ERR("Backend Unknown state, forcing shutdown\n");
- return -1;
- case XenbusStateClosed:
- TPMFRONT_LOG("Backend Closed\n");
- return 0;
- case XenbusStateInitWait:
- TPMFRONT_LOG("Backend Closed (waiting for reconnect)\n");
- return 0;
- default:
- xenbus_wait_for_watch(events);
- }
- }
-
-}
-
-static int wait_for_backend_state_changed(struct tpmfront_dev* dev, XenbusState state) {
- char* err;
- int ret = 0;
- xenbus_event_queue events = NULL;
- char path[512];
-
- snprintf(path, 512, "%s/state", dev->bepath);
- /*Setup the watch to wait for the backend */
- if((err = xenbus_watch_path_token(XBT_NIL, path, path, &events))) {
- TPMFRONT_ERR("Could not set a watch on %s, error was %s\n", path, err);
- free(err);
- return -1;
- }
-
- /* Do the actual wait loop now */
- switch(state) {
- case XenbusStateConnected:
- ret = wait_for_backend_connect(&events, path);
- break;
- case XenbusStateClosed:
- ret = wait_for_backend_closed(&events, path);
- break;
- default:
- TPMFRONT_ERR("Bad wait state %d, ignoring\n", state);
- }
-
- if((err = xenbus_unwatch_path_token(XBT_NIL, path, path))) {
- TPMFRONT_ERR("Unable to unwatch %s, error was %s, ignoring..\n", path, err);
- free(err);
- }
- return ret;
-}
-
-static int tpmfront_connect(struct tpmfront_dev* dev)
-{
- char* err;
- /* Create shared page */
- dev->page = (tpmif_shared_page_t *)alloc_page();
- if(dev->page == NULL) {
- TPMFRONT_ERR("Unable to allocate page for shared memory\n");
- goto error;
- }
- memset(dev->page, 0, PAGE_SIZE);
- dev->ring_ref = gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->page), 0);
- TPMFRONT_DEBUG("grant ref is %lu\n", (unsigned long) dev->ring_ref);
-
- /*Create event channel */
- if(evtchn_alloc_unbound(dev->bedomid, tpmfront_handler, dev, &dev->evtchn)) {
- TPMFRONT_ERR("Unable to allocate event channel\n");
- goto error_postmap;
- }
- unmask_evtchn(dev->evtchn);
- TPMFRONT_DEBUG("event channel is %lu\n", (unsigned long) dev->evtchn);
-
- /* Write the entries to xenstore */
- if(publish_xenbus(dev)) {
- goto error_postevtchn;
- }
-
- /* Change state to connected */
- dev->state = XenbusStateConnected;
-
- /* Tell the backend that we are ready */
- if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", dev->state))) {
- TPMFRONT_ERR("Unable to write to xenstore %s/state, value=%u", dev->nodename, XenbusStateConnected);
- free(err);
- goto error;
- }
-
- return 0;
-error_postevtchn:
- mask_evtchn(dev->evtchn);
- unbind_evtchn(dev->evtchn);
-error_postmap:
- gnttab_end_access(dev->ring_ref);
- free_page(dev->page);
-error:
- return -1;
-}
-
-struct tpmfront_dev* init_tpmfront(const char* _nodename)
-{
- struct tpmfront_dev* dev;
- const char* nodename;
- char path[512];
- char* value, *err;
- unsigned long long ival;
-
- printk("============= Init TPM Front ================\n");
-
- dev = malloc(sizeof(struct tpmfront_dev));
- memset(dev, 0, sizeof(struct tpmfront_dev));
-
-#ifdef HAVE_LIBC
- dev->fd = -1;
-#endif
-
- nodename = _nodename ? _nodename : "device/vtpm/0";
- dev->nodename = strdup(nodename);
-
- init_waitqueue_head(&dev->waitq);
-
- /* Get backend domid */
- snprintf(path, 512, "%s/backend-id", dev->nodename);
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
- free(err);
- goto error;
- }
- if(sscanf(value, "%llu", &ival) != 1) {
- TPMFRONT_ERR("%s has non-integer value (%s)\n", path, value);
- free(value);
- goto error;
- }
- free(value);
- dev->bedomid = ival;
-
- /* Get backend xenstore path */
- snprintf(path, 512, "%s/backend", dev->nodename);
- if((err = xenbus_read(XBT_NIL, path, &dev->bepath))) {
- TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
- free(err);
- goto error;
- }
-
- /* Publish protocol v2 feature */
- snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename);
- if ((err = xenbus_write(XBT_NIL, path, "1")))
- {
- TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", err);
- free(err);
- goto error;
- }
-
- /* Create and publish grant reference and event channel */
- if (tpmfront_connect(dev)) {
- goto error;
- }
-
- /* Wait for backend to connect */
- if( wait_for_backend_state_changed(dev, XenbusStateConnected)) {
- goto error;
- }
-
- /* Ensure backend is also using protocol v2 */
- snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath);
- if((err = xenbus_read(XBT_NIL, path, &value))) {
- TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
- free(err);
- goto error;
- }
- if(strcmp(value, "1")) {
- TPMFRONT_ERR("%s has an invalid value (%s)\n", path, value);
- free(value);
- goto error;
- }
- free(value);
-
- TPMFRONT_LOG("Initialization Completed successfully\n");
-
- return dev;
-
-error:
- shutdown_tpmfront(dev);
- return NULL;
-}
-void shutdown_tpmfront(struct tpmfront_dev* dev)
-{
- char* err;
- char path[512];
- if(dev == NULL) {
- return;
- }
- TPMFRONT_LOG("Shutting down tpmfront\n");
- /* disconnect */
- if(dev->state == XenbusStateConnected) {
- /* Tell backend we are closing */
- dev->state = XenbusStateClosing;
- if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", (unsigned int) dev->state))) {
- TPMFRONT_ERR("Unable to write to %s, error was %s", dev->nodename, err);
- free(err);
- }
-
- /* Clean up xenstore entries */
- snprintf(path, 512, "%s/event-channel", dev->nodename);
- if((err = xenbus_rm(XBT_NIL, path))) {
- free(err);
- }
- snprintf(path, 512, "%s/ring-ref", dev->nodename);
- if((err = xenbus_rm(XBT_NIL, path))) {
- free(err);
- }
-
- /* Tell backend we are closed */
- dev->state = XenbusStateClosed;
- if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", (unsigned int) dev->state))) {
- TPMFRONT_ERR("Unable to write to %s, error was %s", dev->nodename, err);
- free(err);
- }
-
- /* Wait for the backend to close and unmap shared pages, ignore any errors */
- wait_for_backend_state_changed(dev, XenbusStateClosed);
-
- /* Prepare for a later reopen (possibly by a kexec'd kernel) */
- dev->state = XenbusStateInitialising;
- if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", (unsigned int) dev->state))) {
- TPMFRONT_ERR("Unable to write to %s, error was %s", dev->nodename, err);
- free(err);
- }
-
- /* Close event channel and unmap shared page */
- mask_evtchn(dev->evtchn);
- unbind_evtchn(dev->evtchn);
- gnttab_end_access(dev->ring_ref);
-
- free_page(dev->page);
- }
-
- /* Cleanup memory usage */
- if(dev->respbuf) {
- free(dev->respbuf);
- }
- if(dev->bepath) {
- free(dev->bepath);
- }
- if(dev->nodename) {
- free(dev->nodename);
- }
- free(dev);
-}
-
-int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_t length)
-{
- unsigned int offset;
- tpmif_shared_page_t *shr = NULL;
-#ifdef TPMFRONT_PRINT_DEBUG
- int i;
-#endif
- /* Error Checking */
- if(dev == NULL || dev->state != XenbusStateConnected) {
- TPMFRONT_ERR("Tried to send message through disconnected frontend\n");
- return -1;
- }
- shr = dev->page;
-
-#ifdef TPMFRONT_PRINT_DEBUG
- TPMFRONT_DEBUG("Sending Msg to backend size=%u", (unsigned int) length);
- for(i = 0; i < length; ++i) {
- if(!(i % 30)) {
- TPMFRONT_DEBUG_MORE("\n");
- }
- TPMFRONT_DEBUG_MORE("%02X ", msg[i]);
- }
- TPMFRONT_DEBUG_MORE("\n");
-#endif
-
- /* Copy to shared pages now */
- offset = sizeof(*shr);
- if (length + offset > PAGE_SIZE) {
- TPMFRONT_ERR("Message too long for shared page\n");
- return -1;
- }
- memcpy(offset + (uint8_t*)shr, msg, length);
- shr->length = length;
- barrier();
- shr->state = TPMIF_STATE_SUBMIT;
-
- dev->waiting = 1;
- dev->resplen = 0;
-#ifdef HAVE_LIBC
- if(dev->fd >= 0) {
- files[dev->fd].read = 0;
- files[dev->fd].tpmfront.respgot = 0;
- files[dev->fd].tpmfront.offset = 0;
- }
-#endif
- wmb();
- notify_remote_via_evtchn(dev->evtchn);
- return 0;
-}
-int tpmfront_recv(struct tpmfront_dev* dev, uint8_t** msg, size_t *length)
-{
- unsigned int offset;
- tpmif_shared_page_t *shr = NULL;
-#ifdef TPMFRONT_PRINT_DEBUG
-int i;
-#endif
- if(dev == NULL || dev->state != XenbusStateConnected) {
- TPMFRONT_ERR("Tried to receive message from disconnected frontend\n");
- return -1;
- }
- /*Wait for the response */
- wait_event(dev->waitq, (!dev->waiting));
- shr = dev->page;
-
- /* Initialize */
- *msg = NULL;
- *length = 0;
- offset = sizeof(*shr);
-
- if (shr->state != TPMIF_STATE_FINISH)
- goto quit;
-
- *length = shr->length;
-
- if (*length + offset > PAGE_SIZE) {
- TPMFRONT_ERR("Reply too long for shared page\n");
- return -1;
- }
-
- /* Alloc the buffer */
- if(dev->respbuf) {
- free(dev->respbuf);
- }
- *msg = dev->respbuf = malloc(*length);
- dev->resplen = *length;
-
- /* Copy the bits */
- memcpy(*msg, offset + (uint8_t*)shr, *length);
-
-#ifdef TPMFRONT_PRINT_DEBUG
- TPMFRONT_DEBUG("Received response from backend size=%u", (unsigned int) *length);
- for(i = 0; i < *length; ++i) {
- if(!(i % 30)) {
- TPMFRONT_DEBUG_MORE("\n");
- }
- TPMFRONT_DEBUG_MORE("%02X ", (*msg)[i]);
- }
- TPMFRONT_DEBUG_MORE("\n");
-#endif
-#ifdef HAVE_LIBC
- if(dev->fd >= 0) {
- files[dev->fd].tpmfront.respgot = 1;
- }
-#endif
-quit:
- return 0;
-}
-
-int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen)
-{
- int rc;
- if((rc = tpmfront_send(dev, req, reqlen))) {
- return rc;
- }
- if((rc = tpmfront_recv(dev, resp, resplen))) {
- return rc;
- }
-
- return 0;
-}
-
-int tpmfront_set_locality(struct tpmfront_dev* dev, int locality)
-{
- if (!dev || !dev->page)
- return -1;
- dev->page->locality = locality;
- return 0;
-}
-
-#ifdef HAVE_LIBC
-#include <errno.h>
-int tpmfront_open(struct tpmfront_dev* dev)
-{
- /* Silently prevent multiple opens */
- if(dev->fd != -1) {
- return dev->fd;
- }
-
- dev->fd = alloc_fd(FTYPE_TPMFRONT);
- printk("tpmfront_open(%s) -> %d\n", dev->nodename, dev->fd);
- files[dev->fd].tpmfront.dev = dev;
- files[dev->fd].tpmfront.offset = 0;
- files[dev->fd].tpmfront.respgot = 0;
- return dev->fd;
-}
-
-int tpmfront_posix_write(int fd, const uint8_t* buf, size_t count)
-{
- int rc;
- struct tpmfront_dev* dev;
- dev = files[fd].tpmfront.dev;
-
- if(count == 0) {
- return 0;
- }
-
- /* Return an error if we are already processing a command */
- if(dev->waiting) {
- errno = EINPROGRESS;
- return -1;
- }
- /* Send the command now */
- if((rc = tpmfront_send(dev, buf, count)) != 0) {
- errno = EIO;
- return -1;
- }
- return count;
-}
-
-int tpmfront_posix_read(int fd, uint8_t* buf, size_t count)
-{
- int rc;
- uint8_t* dummybuf;
- size_t dummysz;
- struct tpmfront_dev* dev;
-
- dev = files[fd].tpmfront.dev;
-
- if(count == 0) {
- return 0;
- }
-
- /* get the response if we haven't already */
- if(files[dev->fd].tpmfront.respgot == 0) {
- if ((rc = tpmfront_recv(dev, &dummybuf, &dummysz)) != 0) {
- errno = EIO;
- return -1;
- }
- }
-
- /* handle EOF case */
- if(files[dev->fd].tpmfront.offset >= dev->resplen) {
- return 0;
- }
-
- /* Compute the number of bytes and do the copy operation */
- if((rc = min(count, dev->resplen - files[dev->fd].tpmfront.offset)) != 0) {
- memcpy(buf, dev->respbuf + files[dev->fd].tpmfront.offset, rc);
- files[dev->fd].tpmfront.offset += rc;
- }
-
- return rc;
-}
-
-int tpmfront_posix_fstat(int fd, struct stat* buf)
-{
- uint8_t* dummybuf;
- size_t dummysz;
- int rc;
- struct tpmfront_dev* dev = files[fd].tpmfront.dev;
-
- /* If we have a response waiting, then read it now from the backend
- * so we can get its length*/
- if(dev->waiting || (files[dev->fd].read == 1 && !files[dev->fd].tpmfront.respgot)) {
- if ((rc = tpmfront_recv(dev, &dummybuf, &dummysz)) != 0) {
- errno = EIO;
- return -1;
- }
- }
-
- buf->st_mode = O_RDWR;
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_size = dev->resplen;
- buf->st_atime = buf->st_mtime = buf->st_ctime = time(NULL);
-
- return 0;
-}
-
-
-#endif
+++ /dev/null
-/*
- ****************************************************************************
- * (C) 2006 - Cambridge University
- ****************************************************************************
- *
- * File: xenbus.c
- * Author: Steven Smith (sos22@cam.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- * Changes: John D. Ramsdell
- *
- * Date: Jun 2006, chages Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: Minimal implementation of xenbus
- *
- ****************************************************************************
- **/
-#include <inttypes.h>
-#include <mini-os/os.h>
-#include <mini-os/mm.h>
-#include <mini-os/traps.h>
-#include <mini-os/lib.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/events.h>
-#include <mini-os/errno.h>
-#include <mini-os/sched.h>
-#include <mini-os/wait.h>
-#include <xen/io/xs_wire.h>
-#include <mini-os/spinlock.h>
-#include <mini-os/xmalloc.h>
-
-#define min(x,y) ({ \
- typeof(x) tmpx = (x); \
- typeof(y) tmpy = (y); \
- tmpx < tmpy ? tmpx : tmpy; \
- })
-
-#ifdef XENBUS_DEBUG
-#define DEBUG(_f, _a...) \
- printk("MINI_OS(file=xenbus.c, line=%d) " _f , __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...) ((void)0)
-#endif
-
-static struct xenstore_domain_interface *xenstore_buf;
-static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue);
-
-xenbus_event_queue xenbus_events;
-static struct watch {
- char *token;
- xenbus_event_queue *events;
- struct watch *next;
-} *watches;
-struct xenbus_req_info
-{
- int in_use:1;
- struct wait_queue_head waitq;
- void *reply;
-};
-
-#define NR_REQS 32
-static struct xenbus_req_info req_info[NR_REQS];
-
-static void memcpy_from_ring(const void *Ring,
- void *Dest,
- int off,
- int len)
-{
- int c1, c2;
- const char *ring = Ring;
- char *dest = Dest;
- c1 = min(len, XENSTORE_RING_SIZE - off);
- c2 = len - c1;
- memcpy(dest, ring + off, c1);
- memcpy(dest + c1, ring, c2);
-}
-
-char **xenbus_wait_for_watch_return(xenbus_event_queue *queue)
-{
- struct xenbus_event *event;
- DEFINE_WAIT(w);
- if (!queue)
- queue = &xenbus_events;
- while (!(event = *queue)) {
- add_waiter(w, xenbus_watch_queue);
- schedule();
- }
- remove_waiter(w, xenbus_watch_queue);
- *queue = event->next;
- return &event->path;
-}
-
-void xenbus_wait_for_watch(xenbus_event_queue *queue)
-{
- char **ret;
- if (!queue)
- queue = &xenbus_events;
- ret = xenbus_wait_for_watch_return(queue);
- if (ret)
- free(ret);
- else
- printk("unexpected path returned by watch\n");
-}
-
-char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_queue *queue)
-{
- if (!queue)
- queue = &xenbus_events;
- for(;;)
- {
- char *res, *msg;
- int r;
-
- msg = xenbus_read(XBT_NIL, path, &res);
- if(msg) return msg;
-
- r = strcmp(value,res);
- free(res);
-
- if(r==0) break;
- else xenbus_wait_for_watch(queue);
- }
- return NULL;
-}
-
-char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, XenbusState state)
-{
- char *current_state;
- char *msg = NULL;
- char *msg2 = NULL;
- char value[2];
- XenbusState rs;
- int xbt_flag = 0;
- int retry = 0;
-
- do {
- if (xbt == XBT_NIL) {
- msg = xenbus_transaction_start(&xbt);
- if (msg) goto exit;
- xbt_flag = 1;
- }
-
- msg = xenbus_read(xbt, path, ¤t_state);
- if (msg) goto exit;
-
- rs = (XenbusState) (current_state[0] - '0');
- free(current_state);
- if (rs == state) {
- msg = NULL;
- goto exit;
- }
-
- snprintf(value, 2, "%d", state);
- msg = xenbus_write(xbt, path, value);
-
-exit:
- if (xbt_flag) {
- msg2 = xenbus_transaction_end(xbt, 0, &retry);
- xbt = XBT_NIL;
- }
- if (msg == NULL && msg2 != NULL)
- msg = msg2;
- } while (retry);
-
- return msg;
-}
-
-char *xenbus_wait_for_state_change(const char* path, XenbusState *state, xenbus_event_queue *queue)
-{
- if (!queue)
- queue = &xenbus_events;
- for(;;)
- {
- char *res, *msg;
- XenbusState rs;
-
- msg = xenbus_read(XBT_NIL, path, &res);
- if(msg) return msg;
-
- rs = (XenbusState) (res[0] - 48);
- free(res);
-
- if (rs == *state)
- xenbus_wait_for_watch(queue);
- else {
- *state = rs;
- break;
- }
- }
- return NULL;
-}
-
-
-static void xenbus_thread_func(void *ign)
-{
- struct xsd_sockmsg msg;
- unsigned prod = xenstore_buf->rsp_prod;
-
- for (;;)
- {
- wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
- while (1)
- {
- prod = xenstore_buf->rsp_prod;
- DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
- xenstore_buf->rsp_prod);
- if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
- break;
- rmb();
- memcpy_from_ring(xenstore_buf->rsp,
- &msg,
- MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
- sizeof(msg));
- DEBUG("Msg len %d, %d avail, id %d.\n",
- msg.len + sizeof(msg),
- xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
- msg.req_id);
- if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
- sizeof(msg) + msg.len)
- break;
-
- DEBUG("Message is good.\n");
-
- if(msg.type == XS_WATCH_EVENT)
- {
- struct xenbus_event *event = malloc(sizeof(*event) + msg.len);
- xenbus_event_queue *events = NULL;
- char *data = (char*)event + sizeof(*event);
- struct watch *watch;
-
- memcpy_from_ring(xenstore_buf->rsp,
- data,
- MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)),
- msg.len);
-
- event->path = data;
- event->token = event->path + strlen(event->path) + 1;
-
- xenstore_buf->rsp_cons += msg.len + sizeof(msg);
-
- for (watch = watches; watch; watch = watch->next)
- if (!strcmp(watch->token, event->token)) {
- events = watch->events;
- break;
- }
-
- if (events) {
- event->next = *events;
- *events = event;
- wake_up(&xenbus_watch_queue);
- } else {
- printk("unexpected watch token %s\n", event->token);
- free(event);
- }
- }
-
- else
- {
- req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
- memcpy_from_ring(xenstore_buf->rsp,
- req_info[msg.req_id].reply,
- MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
- msg.len + sizeof(msg));
- xenstore_buf->rsp_cons += msg.len + sizeof(msg);
- wake_up(&req_info[msg.req_id].waitq);
- }
- }
- }
-}
-
-static void xenbus_evtchn_handler(evtchn_port_t port, struct pt_regs *regs,
- void *ign)
-{
- wake_up(&xb_waitq);
-}
-
-static int nr_live_reqs;
-static DEFINE_SPINLOCK(req_lock);
-static DECLARE_WAIT_QUEUE_HEAD(req_wq);
-
-/* Release a xenbus identifier */
-static void release_xenbus_id(int id)
-{
- BUG_ON(!req_info[id].in_use);
- spin_lock(&req_lock);
- req_info[id].in_use = 0;
- nr_live_reqs--;
- req_info[id].in_use = 0;
- if (nr_live_reqs == NR_REQS - 1)
- wake_up(&req_wq);
- spin_unlock(&req_lock);
-}
-
-/* Allocate an identifier for a xenbus request. Blocks if none are
- available. */
-static int allocate_xenbus_id(void)
-{
- static int probe;
- int o_probe;
-
- while (1)
- {
- spin_lock(&req_lock);
- if (nr_live_reqs < NR_REQS)
- break;
- spin_unlock(&req_lock);
- wait_event(req_wq, (nr_live_reqs < NR_REQS));
- }
-
- o_probe = probe;
- for (;;)
- {
- if (!req_info[o_probe].in_use)
- break;
- o_probe = (o_probe + 1) % NR_REQS;
- BUG_ON(o_probe == probe);
- }
- nr_live_reqs++;
- req_info[o_probe].in_use = 1;
- probe = (o_probe + 1) % NR_REQS;
- spin_unlock(&req_lock);
- init_waitqueue_head(&req_info[o_probe].waitq);
-
- return o_probe;
-}
-
-/* Initialise xenbus. */
-void init_xenbus(void)
-{
- int err;
- DEBUG("init_xenbus called.\n");
- xenstore_buf = mfn_to_virt(start_info.store_mfn);
- create_thread("xenstore", xenbus_thread_func, NULL);
- DEBUG("buf at %p.\n", xenstore_buf);
- err = bind_evtchn(start_info.store_evtchn,
- xenbus_evtchn_handler,
- NULL);
- unmask_evtchn(start_info.store_evtchn);
- printk("xenbus initialised on irq %d mfn %#lx\n",
- err, start_info.store_mfn);
-}
-
-void fini_xenbus(void)
-{
-}
-
-/* Send data to xenbus. This can block. All of the requests are seen
- by xenbus as if sent atomically. The header is added
- automatically, using type %type, req_id %req_id, and trans_id
- %trans_id. */
-static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
- const struct write_req *req, int nr_reqs)
-{
- XENSTORE_RING_IDX prod;
- int r;
- int len = 0;
- const struct write_req *cur_req;
- int req_off;
- int total_off;
- int this_chunk;
- struct xsd_sockmsg m = {.type = type, .req_id = req_id,
- .tx_id = trans_id };
- struct write_req header_req = { &m, sizeof(m) };
-
- for (r = 0; r < nr_reqs; r++)
- len += req[r].len;
- m.len = len;
- len += sizeof(m);
-
- cur_req = &header_req;
-
- BUG_ON(len > XENSTORE_RING_SIZE);
- /* Wait for the ring to drain to the point where we can send the
- message. */
- prod = xenstore_buf->req_prod;
- if (prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE)
- {
- /* Wait for there to be space on the ring */
- DEBUG("prod %d, len %d, cons %d, size %d; waiting.\n",
- prod, len, xenstore_buf->req_cons, XENSTORE_RING_SIZE);
- wait_event(xb_waitq,
- xenstore_buf->req_prod + len - xenstore_buf->req_cons <=
- XENSTORE_RING_SIZE);
- DEBUG("Back from wait.\n");
- prod = xenstore_buf->req_prod;
- }
-
- /* We're now guaranteed to be able to send the message without
- overflowing the ring. Do so. */
- total_off = 0;
- req_off = 0;
- while (total_off < len)
- {
- this_chunk = min(cur_req->len - req_off,
- XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
- memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
- (char *)cur_req->data + req_off, this_chunk);
- prod += this_chunk;
- req_off += this_chunk;
- total_off += this_chunk;
- if (req_off == cur_req->len)
- {
- req_off = 0;
- if (cur_req == &header_req)
- cur_req = req;
- else
- cur_req++;
- }
- }
-
- DEBUG("Complete main loop of xb_write.\n");
- BUG_ON(req_off != 0);
- BUG_ON(total_off != len);
- BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
-
- /* Remote must see entire message before updating indexes */
- wmb();
-
- xenstore_buf->req_prod += len;
-
- /* Send evtchn to notify remote */
- notify_remote_via_evtchn(start_info.store_evtchn);
-}
-
-/* Send a mesasge to xenbus, in the same fashion as xb_write, and
- block waiting for a reply. The reply is malloced and should be
- freed by the caller. */
-struct xsd_sockmsg *
-xenbus_msg_reply(int type,
- xenbus_transaction_t trans,
- struct write_req *io,
- int nr_reqs)
-{
- int id;
- DEFINE_WAIT(w);
- struct xsd_sockmsg *rep;
-
- id = allocate_xenbus_id();
- add_waiter(w, req_info[id].waitq);
-
- xb_write(type, id, trans, io, nr_reqs);
-
- schedule();
- remove_waiter(w, req_info[id].waitq);
- wake(current);
-
- rep = req_info[id].reply;
- BUG_ON(rep->req_id != id);
- release_xenbus_id(id);
- return rep;
-}
-
-static char *errmsg(struct xsd_sockmsg *rep)
-{
- char *res;
- if (!rep) {
- char msg[] = "No reply";
- size_t len = strlen(msg) + 1;
- return memcpy(malloc(len), msg, len);
- }
- if (rep->type != XS_ERROR)
- return NULL;
- res = malloc(rep->len + 1);
- memcpy(res, rep + 1, rep->len);
- res[rep->len] = 0;
- free(rep);
- return res;
-}
-
-/* Send a debug message to xenbus. Can block. */
-static void xenbus_debug_msg(const char *msg)
-{
- int len = strlen(msg);
- struct write_req req[] = {
- { "print", sizeof("print") },
- { msg, len },
- { "", 1 }};
- struct xsd_sockmsg *reply;
-
- reply = xenbus_msg_reply(XS_DEBUG, 0, req, ARRAY_SIZE(req));
- printk("Got a reply, type %d, id %d, len %d.\n",
- reply->type, reply->req_id, reply->len);
-}
-
-/* List the contents of a directory. Returns a malloc()ed array of
- pointers to malloc()ed strings. The array is NULL terminated. May
- block. */
-char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
-{
- struct xsd_sockmsg *reply, *repmsg;
- struct write_req req[] = { { pre, strlen(pre)+1 } };
- int nr_elems, x, i;
- char **res, *msg;
-
- repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(repmsg);
- if (msg) {
- *contents = NULL;
- return msg;
- }
- reply = repmsg + 1;
- for (x = nr_elems = 0; x < repmsg->len; x++)
- nr_elems += (((char *)reply)[x] == 0);
- res = malloc(sizeof(res[0]) * (nr_elems + 1));
- for (x = i = 0; i < nr_elems; i++) {
- int l = strlen((char *)reply + x);
- res[i] = malloc(l + 1);
- memcpy(res[i], (char *)reply + x, l + 1);
- x += l + 1;
- }
- res[i] = NULL;
- free(repmsg);
- *contents = res;
- return NULL;
-}
-
-char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
-{
- struct write_req req[] = { {path, strlen(path) + 1} };
- struct xsd_sockmsg *rep;
- char *res, *msg;
- rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(rep);
- if (msg) {
- *value = NULL;
- return msg;
- }
- res = malloc(rep->len + 1);
- memcpy(res, rep + 1, rep->len);
- res[rep->len] = 0;
- free(rep);
- *value = res;
- return NULL;
-}
-
-char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value)
-{
- struct write_req req[] = {
- {path, strlen(path) + 1},
- {value, strlen(value)},
- };
- struct xsd_sockmsg *rep;
- char *msg;
- rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(rep);
- if (msg) return msg;
- free(rep);
- return NULL;
-}
-
-char* xenbus_watch_path_token( xenbus_transaction_t xbt, const char *path, const char *token, xenbus_event_queue *events)
-{
- struct xsd_sockmsg *rep;
-
- struct write_req req[] = {
- {path, strlen(path) + 1},
- {token, strlen(token) + 1},
- };
-
- struct watch *watch = malloc(sizeof(*watch));
-
- char *msg;
-
- if (!events)
- events = &xenbus_events;
-
- watch->token = strdup(token);
- watch->events = events;
- watch->next = watches;
- watches = watch;
-
- rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req));
-
- msg = errmsg(rep);
- if (msg) return msg;
- free(rep);
-
- return NULL;
-}
-
-char* xenbus_unwatch_path_token( xenbus_transaction_t xbt, const char *path, const char *token)
-{
- struct xsd_sockmsg *rep;
-
- struct write_req req[] = {
- {path, strlen(path) + 1},
- {token, strlen(token) + 1},
- };
-
- struct watch *watch, **prev;
-
- char *msg;
-
- rep = xenbus_msg_reply(XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
-
- msg = errmsg(rep);
- if (msg) return msg;
- free(rep);
-
- for (prev = &watches, watch = *prev; watch; prev = &watch->next, watch = *prev)
- if (!strcmp(watch->token, token)) {
- free(watch->token);
- *prev = watch->next;
- free(watch);
- break;
- }
-
- return NULL;
-}
-
-char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
-{
- struct write_req req[] = { {path, strlen(path) + 1} };
- struct xsd_sockmsg *rep;
- char *msg;
- rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(rep);
- if (msg)
- return msg;
- free(rep);
- return NULL;
-}
-
-char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
-{
- struct write_req req[] = { {path, strlen(path) + 1} };
- struct xsd_sockmsg *rep;
- char *res, *msg;
- rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(rep);
- if (msg) {
- *value = NULL;
- return msg;
- }
- res = malloc(rep->len + 1);
- memcpy(res, rep + 1, rep->len);
- res[rep->len] = 0;
- free(rep);
- *value = res;
- return NULL;
-}
-
-#define PERM_MAX_SIZE 32
-char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm)
-{
- char value[PERM_MAX_SIZE];
- struct write_req req[] = {
- {path, strlen(path) + 1},
- {value, 0},
- };
- struct xsd_sockmsg *rep;
- char *msg;
- snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
- req[1].len = strlen(value) + 1;
- rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
- msg = errmsg(rep);
- if (msg)
- return msg;
- free(rep);
- return NULL;
-}
-
-char *xenbus_transaction_start(xenbus_transaction_t *xbt)
-{
- /* xenstored becomes angry if you send a length 0 message, so just
- shove a nul terminator on the end */
- struct write_req req = { "", 1};
- struct xsd_sockmsg *rep;
- char *err;
-
- rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
- err = errmsg(rep);
- if (err)
- return err;
- sscanf((char *)(rep + 1), "%lu", xbt);
- free(rep);
- return NULL;
-}
-
-char *
-xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
-{
- struct xsd_sockmsg *rep;
- struct write_req req;
- char *err;
-
- *retry = 0;
-
- req.data = abort ? "F" : "T";
- req.len = 2;
- rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
- err = errmsg(rep);
- if (err) {
- if (!strcmp(err, "EAGAIN")) {
- *retry = 1;
- free(err);
- return NULL;
- } else {
- return err;
- }
- }
- free(rep);
- return NULL;
-}
-
-int xenbus_read_integer(const char *path)
-{
- char *res, *buf;
- int t;
-
- res = xenbus_read(XBT_NIL, path, &buf);
- if (res) {
- printk("Failed to read %s.\n", path);
- free(res);
- return -1;
- }
- sscanf(buf, "%d", &t);
- free(buf);
- return t;
-}
-
-int xenbus_read_uuid(const char* path, unsigned char uuid[16]) {
- char * res, *buf;
- res = xenbus_read(XBT_NIL, path, &buf);
- if(res) {
- printk("Failed to read %s.\n", path);
- free(res);
- return 0;
- }
- if(strlen(buf) != ((2*16)+4) /* 16 hex bytes and 4 hyphens */
- || sscanf(buf,
- "%2hhx%2hhx%2hhx%2hhx-"
- "%2hhx%2hhx-"
- "%2hhx%2hhx-"
- "%2hhx%2hhx-"
- "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
- uuid, uuid + 1, uuid + 2, uuid + 3,
- uuid + 4, uuid + 5, uuid + 6, uuid + 7,
- uuid + 8, uuid + 9, uuid + 10, uuid + 11,
- uuid + 12, uuid + 13, uuid + 14, uuid + 15) != 16) {
- printk("Xenbus path %s value %s is not a uuid!\n", path, buf);
- free(buf);
- return 0;
- }
- free(buf);
- return 1;
-}
-
-char* xenbus_printf(xenbus_transaction_t xbt,
- const char* node, const char* path,
- const char* fmt, ...)
-{
-#define BUFFER_SIZE 256
- char fullpath[BUFFER_SIZE];
- char val[BUFFER_SIZE];
- va_list args;
-
- BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
- sprintf(fullpath,"%s/%s", node, path);
- va_start(args, fmt);
- vsprintf(val, fmt, args);
- va_end(args);
- return xenbus_write(xbt,fullpath,val);
-}
-
-domid_t xenbus_get_self_id(void)
-{
- char *dom_id;
- domid_t ret;
-
- BUG_ON(xenbus_read(XBT_NIL, "domid", &dom_id));
- sscanf(dom_id, "%"SCNd16, &ret);
-
- return ret;
-}
-
-static void do_ls_test(const char *pre)
-{
- char **dirs, *msg;
- int x;
-
- printk("ls %s...\n", pre);
- msg = xenbus_ls(XBT_NIL, pre, &dirs);
- if (msg) {
- printk("Error in xenbus ls: %s\n", msg);
- free(msg);
- return;
- }
- for (x = 0; dirs[x]; x++)
- {
- printk("ls %s[%d] -> %s\n", pre, x, dirs[x]);
- free(dirs[x]);
- }
- free(dirs);
-}
-
-static void do_read_test(const char *path)
-{
- char *res, *msg;
- printk("Read %s...\n", path);
- msg = xenbus_read(XBT_NIL, path, &res);
- if (msg) {
- printk("Error in xenbus read: %s\n", msg);
- free(msg);
- return;
- }
- printk("Read %s -> %s.\n", path, res);
- free(res);
-}
-
-static void do_write_test(const char *path, const char *val)
-{
- char *msg;
- printk("Write %s to %s...\n", val, path);
- msg = xenbus_write(XBT_NIL, path, val);
- if (msg) {
- printk("Result %s\n", msg);
- free(msg);
- } else {
- printk("Success.\n");
- }
-}
-
-static void do_rm_test(const char *path)
-{
- char *msg;
- printk("rm %s...\n", path);
- msg = xenbus_rm(XBT_NIL, path);
- if (msg) {
- printk("Result %s\n", msg);
- free(msg);
- } else {
- printk("Success.\n");
- }
-}
-
-/* Simple testing thing */
-void test_xenbus(void)
-{
- printk("Doing xenbus test.\n");
- xenbus_debug_msg("Testing xenbus...\n");
-
- printk("Doing ls test.\n");
- do_ls_test("device");
- do_ls_test("device/vif");
- do_ls_test("device/vif/0");
-
- printk("Doing read test.\n");
- do_read_test("device/vif/0/mac");
- do_read_test("device/vif/0/backend");
-
- printk("Doing write test.\n");
- do_write_test("device/vif/0/flibble", "flobble");
- do_read_test("device/vif/0/flibble");
- do_write_test("device/vif/0/flibble", "widget");
- do_read_test("device/vif/0/flibble");
-
- printk("Doing rm test.\n");
- do_rm_test("device/vif/0/flibble");
- do_read_test("device/vif/0/flibble");
- printk("(Should have said ENOENT)\n");
-}
-
-/*
- * Local variables:
- * mode: C
- * c-basic-offset: 4
- * End:
- */